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のデフォルトのシステムシェルはbashではなくdashであるため、使用している場合、スクリプトは予想とは異なるシェルを使用します。Dashにはリダイレクト演算子はありません。#!/bin/sh<<<


14

Docker:

私が持っていたように私は私のDockerfileからこの問題を取得していました:

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

しかし、この問題によると、それは解決されました:

execの形式は、シェルの文字列いじるを回避することができる、とにRUN 含まれていない基本イメージを使用してコマンド/bin/sh

注意

以外の別のシェルを使用するには、目的のシェルを渡すexecフォームを/bin/sh使用します。例えば、

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)"]

パラメーターを囲む引用符に注意してください。


14

以下を使用してスクリプトを実行している場合:

sudo sh ./script.sh

次に、代わりに以下を使用します。

sudo bash ./script.sh

これは、BashがUbuntuのデフォルトのシェルではないためです。したがって、「sh」を使用すると、デフォルトのシェルが使用されます。これは実際にはダッシュです。これは#!/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!

...またはecho 'text' | ncさらに短いです。
phil294

2

より簡単な方法で、

direc=$(basename `pwd`)

またはシェルを使用する

$ direc=${PWD##*/}

1

このエラーのもう1つの理由は、Subversion作業コピーを更新するcronジョブを実行していて、更新後に競合状態にあるバージョン付きスクリプトを実行しようとした場合です...


1

私のマシンでは、スクリプトを直接実行した場合、デフォルトはbashです。

で実行するとsudo、デフォルトはshです。

そのため、を使用しsudoたときにこの問題が発生していました。


0

私の場合、エラーは「>>」を2回入力したためです

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 script_name.sh」を使用してスクリプトを実行します

スクリプトが/ bin / shで始まる場合は、以下のコマンド「sh script_name.sh」を使用してスクリプトを実行します

./sample.sh-スクリプトの最初の行からインタープリターを検出して実行します。

デフォルトとして異なるシェルを持つ異なるLinuxディストリビューション。


1
回答ありがとうございますが、他の回答に加えて付加価値を提供する方がよいでしょう。この場合、別のユーザーがすでにそのソリューションを投稿しているため、あなたの答えは追加の価値を提供しません。以前の回答が参考になった場合は、同じ情報を繰り返すのではなく、投票してください。
Toby Speight

ここで解決策を例に説明したと思いませんか?
Sijeesh

8年前に書かれたJohn Kugelmanの回答で十分にカバーされていないものはありますか?
Toby Speight 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.