これが機能する理由:
[ -r /tmp ] && echo "tt" >/tmp/taa
cat taa
tt
しかし、次はそうではありません。どうすればこの問題を解決し、再利用のための変数を維持できますか?
COMD='[ -r /tmp ] && echo "tt"'
$COMD >/tmp/taa
bash: [: missing `]
ありがとう
編集:eval
うまくいきます。しかし、私はその理由を理解していません。質問、私は重複としてマークされています、説明がありません。また、&&
次から始まる部分を削除すると機能し、実際には次のことなく正しい結果を返しますeval
。
COMD='[ -r /tmp ]'
$COMD
echo $?
0
COMD='[ -r /tmpdddd ]'
$COMD
echo $?
1
答え1
あなたは考えないでしょう:
var='echo test && reboot'
echo $var
エクスポートしてtest
からやり直しても大丈夫ですか?
代わりに出力されます。echo test && reboot
これは次のような場合に便利です。
var='echo test && reboot'
$var
今、混乱しているのは、ほとんどのBourne様シェルでecho test && reboot
コマンドが見つからないというエラーで失敗しないことです。代わりに変更しないと$IFS
出力されますtest && reboot
。
これは、これらのシェルで変数を引用符で囲まないと、一種の分割+グローブ演算子が適用されるためです。
引用符が付けられていないため、単語に分割され$var
ます(特殊引数に基づいて):$IFS
、、、、、、echo
実行するコマンドは最初の()に由来し、すべての単語はコマンドに引数として渡されます。引数です。引用符のないリテラルだけが、その言語の演算子として理解されます。 Cと同様に、C言語の構文に演算子が含まれているとしても、2つの引数を渡すわけではありません。test
&&
reboot
echo
&&
echo
&&
&&
sh
var="foo, bar"; printf(var)
printf
var
,
実際、歴史を振り返ると、1970年代初頭にUNIXの最初のバージョンにさかのぼりますsh
。トンプソンシェル)そこで実行されますreboot
。sh
当時は変数はサポートされていませんでしたが、位置パラメータはありました。
以下は、PDP11エミュレータでUnix V1を使用することです。
$ cat myscript
echo $1
$ sh myscript 'echo test; reboot'
echo test
No command
$ ls -l /bin/sh
total 12
88 lxrwr- 1 sys 5312 Jan 1 00:00:00 sh
reboot
(幸い、当時は命令がなかったためNo command
エラーが発生しました。)
今日の基準では奇妙に聞こえるかもしれませんが、Unix V1は数百キロバイトのメモリとメガバイトの記憶領域を備えたシステムで実行されていたので、当時はすべてを単純に保つ必要がありました。最新のシステム(何も実行しないコマンド)sh
よりもはるかに小さいことを確認してください/bin/true
(私のシステムでは27KB(動的リンカーまたはリンクされた動的ライブラリを除く)、このshの場合は5KB)。
1970年代後半、Unix V7にはsh
当時はまだ新しいBourneシェルが搭載されていました。さらに進化してきたが、それでも以前の製品との互換性を完全に破るわけではない。同様の時期にBSDに登場したcshも同様でした。これはおそらくBourneシェルの厄介な動作の主な理由です。解釈するものではありません)、Thomsonシェルと逆互換可能。
または(Bourneシェルと同様)などの一部のシェルは最終的にこの問題を解決しましたが、多くのシェルはrc
Bourneシェルとの下位互換性を維持します。fish
zsh
bash
文字列をシェルコードとして解釈する場合は、eval
このコマンドの目的は次のとおりです。
eval "$var"
(Bourneなどのシェルで分割+グローブを防ぐために引用符を参照してください)。
しかし、コードを変数に保存するには、他の言語などの関数を使用する方が合理的です。
f() { echo test && reboot; }
答え2
&&
変数拡張後は演算子が認識されないためです。引用符も同じです。有効な場合は印刷されます"tt"
。 (努力するcmd='echo "tt"'; $cmd
:)
関数として作成します。
checktmp() {
[ -r /tmp ] && echo "tt"
}
checktmp
関数はコード用で、変数はデータ用です。