Подтвердить что ты не робот

Присвоить результаты подстановки к переменной в Bash

Мой коллега Райан пришел ко мне с ошибкой в ​​ Bash script, и я определил проблему с этим тестом:

$ mkdir ryan
$ mkdir ryan/smells-bad
$ FOO=ryan/smells-*
$ echo $FOO
ryan/smells-bad
$ touch $FOO/rotten_eggs
touch: cannot touch `ryan/smells-*/rotten_eggs': No such file or directory

Из этого я делаю вывод, что globbing происходит во время команды echo, а не при создании переменной FOO.

У нас есть несколько обходных решений, в порядке убывания беззакония:

touch `echo $FOO`/rotten_eggs

Или:

pushd
cd $FOO
touch rotten_eggs
popd

Но ни одно из них не удовлетворяет. Я пропустил трюк?

4b9b3361

Ответ 1

Проблема заключается в том, что glob будет расширяться только в том случае, если файл "rotten_eggs" существует, потому что он включен в шаблон glob. Вы должны использовать массив.

FOO=( ryan/smells-* )
touch "${FOO[@]/%//rotten_eggs}"

В массиве FOO содержится все, что соответствует glob. Расширение с использованием% добавляет /rotten _eggs к каждому элементу.

Ответ 2

Рассмотрим

for dir in $FOO; do
    touch "$dir/rotten_eggs"
done

Обратите внимание, что это будет touch несколько файлов, если шаблон glob соответствует более чем одному пути.

Ответ 3

Я бы сделал это следующим образом:

for FOO in ryan/smells-*; do
  touch "$FOO"/rotten_eggs
done

Этот способ $FOO содержит фактическое имя каталога, а не шаблон glob. Если есть более одного совпадения, он будет содержать только последний после цикла, поэтому решение массива может быть лучше для этого случая.