"<<(command-here)" идиома оболочки, приводящая к "неожиданному перенаправлению" - PullRequest
5 голосов
/ 13 марта 2012

Эта команда отлично работает:

$ bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)

Однако я не понимаю, как именно stable передается в качестве параметра в скрипт оболочки, который загружается curl. Вот почему я не могу достичь той же функциональности в своем собственном сценарии оболочки - он дает мне ./foo.sh: 2: Syntax error: redirection unexpected:

$ cat foo.sh 
#!/bin/sh
bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)

Итак, вопросы: как именно этот stable параметр попадает в сценарий, почему в этой команде есть два перенаправления, и как мне изменить эту команду, чтобы она работала внутри моего сценария?

1 Ответ

12 голосов
/ 13 марта 2012

Относительно ошибки «неожиданное перенаправление»:

Это не относится к stable, оно связано с вашим сценарием, использующим /bin/sh, а не bash.Синтаксис <() недоступен в оболочках POSIX, который включает bash при вызове как /bin/sh (в этом случае он отключает нестандартную функциональность по соображениям совместимости).

Сделайте строку shebang #!/bin/bash.

Понимание идиомы < <():

Чтобы понять, что происходит - <() заменяется именем файла, которое относится к выводу команды, которую он выполняет;в Linux это обычно имя файла типа /dev/fd/##.Запустив < <(command), вы берете этот файл и направляете его на ваш стандартный ... что довольно близко к поведению канала.

Чтобы понять, почему эта идиома полезна, сравните это:

read foo < <(echo "bar")
echo "$foo"

к этому:

echo "bar" | read foo
echo "$foo"

Первый работает, потому что чтение выполняется той же оболочкой, которая позже повторяет результат.Последнее не происходит, поскольку чтение выполняется в подоболочке, которая была создана только для настройки конвейера, а затем уничтожена, поэтому переменная больше не присутствует для последующего эха.

Понимание bash -s stable:

bash -s указывает на то, что запускаемый скрипт войдет в stdin.Все аргументы затем передаются в сценарий в массиве $@ ($1, $2 и т. Д.), Поэтому stable становится $1 при запуске сценария, введенного в stdin.

...