1

私が持っている場合

if [ ! -e $dir ];
then
 mkdir $dir
fi 

動作しますが、動作しません

[[ ! -e $dir ]] || mkdir $dir 

なぜ ?

編集0

[[ ...私は得る

 line 34: [[ !: command not found

編集1

bash --version
GNU bash, version 3.2.25(1)-release (i686-redhat-linux-gnu)
Copyright (C) 2005 Free Software Foundation, Inc.

編集2

動作する場合と動作しない場合があり、2つの連続したコマンド

[user@host ~]$ [ -e /tmp ] && date
-bash: [: missing `]'
[user@host ~]$ [ -e /tmp ] && date
mar jun 26 10:05:50 CLT 2012
4

3 に答える 3

3

あなたは使用する必要があります

[ ! -e $dir ] && mkdir $dir

単一の「[」はtestを呼び出すためのショートカットであるため、テスト構文が適用されます。代わりに、double "[["は、完全に異なるbashの論理構文を使用します。

また、テストでtrueが返された場合にコマンドを実行するため、「&&」(「||」)を使用する必要があります。構文は、テストがfalseを返した場合にのみコマンドを実行します。

編集:

bashのマニュアルページを確認すると、条件式([[)で得られるものも-e構文を理解していることがわかります。そのセクションでは「!」については触れていません。結果を否定しますが、コマンドラインで試してみると機能します。私の推測では、あなたのシステムは、「!」を理解していない、コメント投稿者とは異なるバージョンのbashを実行している可能性があります。?テストのマニュアルページには、「!」と明記されています。がサポートされているので、あなたの靴では、最初に[]を試して、それが機能するかどうかを確認してから、さらに詳しく調べます。

于 2012-06-25T21:09:46.200 に答える
1

特に編集 2 の後、これは本当に「おかしな」文字の問題のように見えます。印刷されていない文字が混在しているか、改行しないスペースのような通常のように見えますが奇妙な文字です。これらは検出がかなり難しい場合があります。エディターではまったく正常に見えることがありますが、スクリプトをそのようなもので表示したとしても、cat -vおかしな文字がはっきりと表示されるとは限りません。システムにある場合xxd、ファイルの内容を正確に確認するのに非常に良い方法です。このタイプの問題の簡単なデモを次に示します。

$ cat -v nbsptest 
#!/bin/bash -x
[ -e /tmp ] && date
[ -e /tmp ] && date
[ -e /tmp ] && date
$ ./nbsptest 
+ '[ -e' /tmp ']'
./nbsptest: line 2: [ -e: command not found
+ '[' -e '/tmp ]'
./nbsptest: line 3: [: missing `]'
+ '[' -e /tmp ']'
+ date
Sat Jun 30 10:53:56 PDT 2012
$ xxd nbsptest 
0000000: 2321 2f62 696e 2f62 6173 6820 2d78 0a5b  #!/bin/bash -x.[
0000010: c2a0 2d65 202f 746d 7020 5d20 2626 2064  ..-e /tmp ] && d
0000020: 6174 650a 5b20 2d65 202f 746d 70c2 a05d  ate.[ -e /tmp..]
0000030: 2026 2620 6461 7465 0a5b 202d 6520 2f74   && date.[ -e /t
0000040: 6d70 205d 2026 2620 6461 7465 0a         mp ] && date.

スクリプトはcat -v(and morevi、など) で完全に正常に見えますが、最初の 2 つのコマンドは失敗します。 xxd理由を示します: 最初のコマンドは と の間に UTF-8 改行なしスペースが[あり-e(これはテキスト リストの 16 進リストでは c2a0 として示され[..-eます)、2 番目のコマンドはテキスト リストの(/tmpと) の間に改行なしスペースがあります。]/tmp..]

-xディスプレイ(私はそれbash -xを呼び出していましたが、set -x@CodeGnomeが提案したように使用することもできます)は、何が起こっているかについてのヒントも提供します。最初のコマンドでは、'[ -e' /tmp ']'-- の周りの引用符に注意してください[ -e。これは、シェルがすべてを 1 つの「単語」として扱っていることを示しています。同様に、2 番目のコマンドは、すべて 1 つの「単語」'[' -e '/tmp ]'であると見なされていることを示す引用符付きで表示されます。/tmp ]

于 2012-06-30T17:59:49.747 に答える
0

シンタックスワークス

少なくとも、それは私にとってはうまくいきます。例えば:

# Inverted logic. Returns false because directory exists.
$ [[ ! -e /tmp ]]; echo $?
1

本当にBashを使用していますか? シェルとバージョンを確認してください。

$ echo $SHELL $BASH_VERSION
/bin/bash 4.2.10(1)-release

より良いアプローチ

あなたの条件ロジックは少し複雑です。これは、あなたがやりたいことのためのよりきれいな構文です:

dir=/tmp/foo
[[ -e "$dir" ]] || mkdir "$dir"

これは意味的により明確であり、逆のロジックなしで意図を表現します。反転テストが必要な場合もありますが、あなたの例はその 1 つではありません。

于 2012-06-25T21:11:30.883 に答える