web-dev-qa-db-ja.com

単純なBashスクリプトで「予期しないトークン `'$#' 'の近くの構文エラー」が発生します

Debian 1 (Buster)を使用していて、単純なBashスクリプトでエラーが発生します。 1つのパラメーターが渡されているかどうかを確認し、それがファイルの場合はファイルをエコー出力するだけです。

#!/usr/bin/bash
if [ ( '$#' -eq 1 ) && ( -f "$1" ) ]; then
        echo "$1"
fi

exit 1

私はこのエラーを受け取ります:

line 2: syntax error near unexpected token `'$#''
line 2: `if [ ( '$#' -eq 1 ) && ( -f "$1" ) ]; then'

私は$#を囲む引用符のすべての組み合わせ( "、 '、引用符なし)を試しましたが、使用する引用符のタイプを使用してこれらのエラーメッセージのバリアントを常に取得します。見た目がわかりませんために。

4
raphael75

[はコマンドなので、問題は実際に複数の条件を使用しようとしている方法です。あなたはこれを求めている:

if [ "$#" -eq 1 ] && [ -f "$1" ]; then
11
Fox

ここには2つの問題があります。まず、単純な_[_組み込み関数に_&&_を含めることはできません。複数の条件を組み合わせる場合は、複数の_[_が必要です。

_if [ "$#" -eq 1 ] && [ -f "$1" ]; then
_

第2に、_$#_を展開する必要があるため、単一引用符は使用できません。 _'$#' -eq 1_を使用したバージョンは、string _$#_を数値1と比較していました。

代わりにbashの_[[_キーワードを使用すると、全体がはるかに簡単になります。

_if [[  "$#" -eq 1  &&  -f "$1"  ]]; then
_
20
terdon

スクリプトを修正する方法を説明する他の回答にも関わらず、技術的に何のエラーなのか疑問に思いました。 bashがコマンド内のWordを引用符で囲まずエスケープしない(を許可する唯一の有効な構文は、関数を定義するときだと思います。そのため、bashは(を見て、それを[という名前の関数の定義である必要があるとすぐに考えましたが、その後'$#'を続けたため、bashは)しか期待していなかったため、そのため、構文エラーが発生しました。関数の定義ではない場合、それが何であるかを誰が知っているのでしょう。 (以外の)の後は、同じ構文エラーが発生します。

$ echo ( foo )
bash: syntax error near unexpected token `foo'

関数定義の構文に適合しない(に続くものを削除すると、次のようになります。

$ [ ( ) ( -f "$1" )

これは、関数[を定義することになります。

$ [
bash: -f: command not found
8
JoL