Как передать вывод сценария к команде как ls без разделяемого вывода?

Я отправляю этот ответ на основе обсуждения в комментариях.

Метод проб и ошибок указывает на то изменение $TERM от linux кому: xterm работы вокруг проблемы.

Я не знаю, почему это имело бы значение. Из Вашего описания, с TERM=linux это открывает пустой буфер, а не файл, который не является поведением, которое я ожидал бы от плохого $TERM установка. И значение по умолчанию $TERM под screen должен быть "screen" так или иначе, если один из Ваших сценариев запуска не изменяет его.

2
28.02.2013, 16:27
2 ответа

Кавычки использования:

$ ls "$(./myscript)"
3
27.01.2020, 21:57
  • 1
    Это не работает также. –  helpermethod 28.02.2013, 16:17
  • 2
    @helpermethod, который Это делает, и это - правильный ответ, если Вы имеете единственный файл и печатаете просто его имя без кавычек. Корректный –  Gilles 'SO- stop being evil' 28.02.2013, 16:29
  • 3
    @Gilles. Проблема была %q флаг printf встроенного. Изменение этого к %s решенный проблема. –  helpermethod 28.02.2013, 16:38
  • 4
    @Gilles Что относительно того, чтобы печатать несколько файлов? –  helpermethod 28.02.2013, 16:50
  • 5
    К сожалению, передача параметров / механизм разделения слова оболочки не делает это возможным всегда, который и прост и корректен, AFAIK. Необходимо было бы вызвать ls в Вашем сценарии, где у Вас все еще есть отдельные аргументы. Если Вы не хотите к hardcode ls и хочу, чтобы это было различными командами, у Вас мог быть сценарий, берут в команде как аргумент, но сценарий должен был бы все еще быть тем для выполнения его. –  jw013 28.02.2013, 18:06

Замена команды

Если необходимо передать вывод от команды как аргумент другой команде, используйте замену команды. Так же к тому, что происходит с подстановками переменных, результат замены команды подвергается разделению слова (разделяющий на отдельные слова в каждом символе в $IFS, пробел по умолчанию) и подстановочное расширение (globbing имен файлов). Так, всегда используйте двойные кавычки вокруг замен команды, если Вы не хотите разделить и globbing для случая.

ls -- "$(./myscript)"

-- говорит ls чтобы прекратить обрабатывать опции, это необходимо в случае, если имя файла, распечатанное сценарием, начинается -.

Необходимо распечатать литеральные имена файлов. Не добавляйте дополнительное заключение в кавычки из сценария.

Существует на самом деле один пограничный случай, где аргумент искажается: замена команды снимает изоляцию с любой заключительной новой строки от вывода команды. Таким образом, ли вывод foo↲bar или foo↲bar↲ или foo↲bar↲↲↲ (Я использую представить символ новой строки), аргумент ls команда будет справедлива foo↲bar. Этого почти никогда не происходит на практике, потому что, хотя новые строки позволяются в именах файлов, никто не использует их. Тем не менее, это могла быть проблема безопасности, потому что кто-то пытающийся напасть на Вашу систему мог бы поместить новые строки в имя файла.

Для обработки заключительных новых строк примите меры, чтобы команда произвела дополнительный несимвол новой строки и сняла изоляцию с нее от результата замены команды.

output=$(./myscript; echo a)
output="${output%a}"
ls -- "$output"

Передача нескольких имен файлов к команде

Один символ, который не может появиться в имени файла или параметре командной строки, является пустым байтом. Безопасный способ произвести несколько имен файлов или другие аргументы, которые будут переданы команде, состоит в том, чтобы разделить их с пустыми байтами и вызовом xargs -0. Это работает над Linux, *BSD и OSX, но является расширением POSIX, в котором могут испытать недостаток другие варианты Unix. Если получающаяся командная строка является слишком длинной, xargs разделяет ее и вызывает команду многократно.

… | xargs -0 ls

Без -0, xargs ожидает формат ввода, который не производит никакая другая общая команда. Для использования безопасно, если вход не содержит пробела, ни какого-либо из \"'.

Способ заключить вход в кавычки для xargs должен поместить обратную косую черту прежде, по крайней мере, следующие символы: новая строка, вкладка, пространство и \"'.

for x in …; do
  printf '%s\n' "$x" | sed -e 's/[  '\''\"]/\\&/g' -e 's/$/\\$/' -e '$ s/\\$//'
done | xargs ls

Поместите пространство и вкладку вместо этих двух пробелов в скобках в команде sed.

Дальнейшие примечания по незащищенным заменам и заключению в кавычки

В незащищенной переменной или команде susbtitution, для каждого слова, с которым globbing происходит, эти четыре символа \[*? расширены. Однако только символы [*? триггер globbing: обратная косая черта без других globbing символов остается неповрежденной. Таким образом, если текущий каталог содержит три названные файла foo, goo и bar, затем:

  • ls $(echo '?oo bar') вызовы ls с аргументами foo, goo и bar
  • ls $(echo '?\oo b\ar') вызовы ls с аргументами foo, goo и b\ar
2
27.01.2020, 21:57

Теги

Похожие вопросы