Bash: синтаксическая ошибка: перенаправление неожиданно

138

Я делаю это в скрипте:

read direc <<< $(basename `pwd`)

и я получаю:

Syntax error: redirection unexpected

на машине ubuntu

/bin/bash --version
GNU bash, version 4.0.33(1)-release (x86_64-pc-linux-gnu)

пока я не получаю эту ошибку в другой машине suse:

/bin/bash --version
GNU bash, version 3.2.39(1)-release (x86_64-suse-linux-gnu)
Copyright (C) 2007 Free Software Foundation, Inc.

Почему ошибка?

Открой путь
источник
Для справки, команда также работает на cygwin (/ bin / bash --version GNU bash, версия 3.2.49 (23) -release (i686-pc-cygwin) Copyright (C) 2007 Free Software Foundation, Inc.)
хловдал

Ответы:

243

Ваш скрипт ссылается /bin/bashили /bin/shв его строке хеширования? Системной оболочкой по умолчанию в Ubuntu является dash , а не bash , так что если у вас есть, #!/bin/shтогда ваш скрипт будет использовать другую оболочку, чем вы ожидаете. В Dash нет <<<оператора перенаправления.

Джон Кугельман
источник
14

Докер:

Я получал эту проблему из моего Dockerfile, как у меня было:

RUN bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)

Однако по этому вопросу решено было:

Форма exec позволяет избежать перестановки строк оболочки и RUN команд, использующих базовое изображение, которое не содержит /bin/sh.

Заметка

Чтобы использовать другую оболочку, кроме /bin/sh, используйте форму exec, передающую желаемую оболочку. Например,

RUN ["/bin/bash", "-c", "echo hello"]

Решение:

RUN ["/bin/bash", "-c", "bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)"]

Обратите внимание на кавычки вокруг каждого параметра.

Kemicofa Ghost
источник
14

Если для запуска сценария вы используете следующее:

sudo sh ./script.sh

Тогда вы захотите использовать вместо этого следующее:

sudo bash ./script.sh

Причина этого в том, что Bash не является оболочкой по умолчанию для Ubuntu. Итак, если вы используете «sh», то он просто будет использовать оболочку по умолчанию; который на самом деле Dash. Это произойдет независимо от того, есть ли у вас #!/bin/bashверхняя часть вашего скрипта. В результате вам нужно будет явно указать использование, bashкак показано выше, и ваш скрипт должен работать в ожидаемом режиме.

Dash не поддерживает перенаправления так же, как Bash.

Крис Питчманн
источник
6

Вы можете получить результат этой команды и поместить его в переменную. тогда используйте heredoc. например:

nc -l -p 80 <<< "tested like a charm";

можно написать так:

nc -l -p 80 <<EOF
tested like a charm
EOF

и вот так (это то, что вы хотите):

text="tested like a charm"
nc -l -p 80 <<EOF
$text
EOF

Практический пример в busyboxнижнем dockerконтейнере:

kasra@ubuntu:~$ docker run --rm -it busybox
/ # nc -l -p 80 <<< "tested like a charm";
sh: syntax error: unexpected redirection


/ # nc -l -p 80 <<EOL
> tested like a charm
> EOL
^Cpunt!       => socket listening, no errors. ^Cpunt! is result of CTRL+C signal.


/ # text="tested like a charm"
/ # nc -l -p 80 <<EOF
> $text
> EOF
^Cpunt!
AmirHossein
источник
... или echo 'text' | ncчто еще короче.
phil294 08
2

сделай это проще,

direc=$(basename `pwd`)

Или используйте оболочку

$ direc=${PWD##*/}
ghostdog74
источник
1

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

Мотин
источник
1

На моем компьютере, если я запускаю скрипт напрямую, по умолчанию используется bash.

Если я запустил его sudo, по умолчанию будет sh.

Вот почему я столкнулся с этой проблемой, когда использовал sudo.

Майкл Мазер
источник
0

В моем случае ошибка связана с тем, что я дважды поставил ">>"

mongodump --db=$DB_NAME --collection=$col --out=$BACKUP_LOCATION/$DB_NAME-$BACKUP_DATE >> >> $LOG_PATH

я просто исправляю это как

mongodump --db=$DB_NAME --collection=$col --out=$BACKUP_LOCATION/$DB_NAME-$BACKUP_DATE >> $LOG_PATH
Мансур Али
источник
0

Перед запуском скрипта вы должны проверить первую строку скрипта для интерпретатора.

Например: если сценарии начинаются с / bin / bash, запустите сценарий, используя команду ниже "bash имя_сценария.sh"

если скрипт начинается с / bin / sh, запустите скрипт с помощью следующей команды "sh script_name.sh"

./sample.sh - это обнаружит интерпретатор из первой строки скрипта и запустится.

Разные дистрибутивы Linux имеют разные оболочки по умолчанию.

Sijeesh
источник
1
Хотя мы благодарим вас за ваш ответ, было бы лучше, если бы он предоставил дополнительную ценность поверх других ответов. В этом случае ваш ответ не дает дополнительной ценности, так как другой пользователь уже опубликовал это решение. Если предыдущий ответ был вам полезен, вы должны проголосовать за него, а не повторять ту же информацию.
Тоби Спейт
Вам не кажется, что я объяснил решение здесь на примере?
Сиджеш
Есть ли здесь что-то, что не было должным образом отражено в ответе Джона Кугельмана, написанном 8 лет назад?
Тоби Спейт