Bash: синтаксическая ошибка: перенаправление неожиданно
Я делаю это в сценарии:
read direc <<< $(basename `pwd`)
и я получаю:
Syntax error: redirection unexpected
в машине с убунту
/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.
Почему ошибка?
10 ответов
Ссылка на ваш скрипт /bin/bash
или же /bin/sh
в его хэш-линии взрыва? Системной оболочкой по умолчанию в Ubuntu является dash, а не bash, так что если у вас есть #!/bin/sh
тогда ваш скрипт будет использовать другую оболочку, чем вы ожидаете. Тире не имеет <<<
оператор перенаправления.
Если вы используете следующее для запуска вашего скрипта:
sudo sh ./script.sh
Тогда вы захотите использовать следующее:
sudo bash ./script.sh
Причина этого в том, что Bash не является оболочкой по умолчанию для Ubuntu. Итак, если вы используете "sh", то он будет использовать оболочку по умолчанию; который на самом деле Dash. Это произойдет независимо от того, если у вас есть #!/bin/bash
в верхней части вашего сценария. В результате вам нужно будет явно указать для использования bash
как показано выше, и ваш скрипт должен работать с ожидаемым.
Dash не поддерживает перенаправления так же, как Bash.
Докер:
Я получал эту проблему из моего 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)"]
Обратите внимание на кавычки вокруг каждого параметра.
Вы можете получить вывод этой команды и поместить его в переменную. затем используйте 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!
Сделать это более простым способом,
direc=$(basename `pwd`)
Или используйте оболочку
$ direc=${PWD##*/}
Другая причина ошибки может заключаться в том, что вы запускаете задание cron, которое обновляет рабочую копию Subversion, а затем пытается запустить версионный скрипт, который находился в конфликтном состоянии после обновления...
На моем компьютере, если я запускаю скрипт напрямую, по умолчанию bash
,
Если я запускаю его с sudo
по умолчанию sh
,
Вот почему я столкнулся с этой проблемой, когда я использовал sudo
,
Пункт 1:#!/bin/bash
Пункт 2. Убедитесь, что у вашего файла есть соответствующие разрешения (для примера sh-файлаchmod 777 test.sh
)
Пункт 3:./test.sh
, не используйsh test.sh
В моем случае ошибка в том, что я поставил ">>" дважды
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
Перед запуском скрипта вы должны проверить первую строку скрипта для интерпретатора.
Например: если сценарии начинаются с /bin/bash, запустите сценарий с помощью приведенной ниже команды "bash script_name.sh"
если скрипт начинается с /bin/sh, запустите скрипт с помощью следующей команды "sh script_name.sh"
./sample.sh - это обнаружит интерпретатор из первой строки скрипта и запустится.
Разные дистрибутивы Linux имеют разные оболочки по умолчанию.