テールコマンドをエコーすると、予期しない出力が生成されますか?


8

このコマンドを単独で実行すると、期待される結果(crontabの最後の行)が生成されます。

tail -n 1 /etc/crontab

ただし、echoコマンドの一部として実行して結果をファイルに送信すると、作業ディレクトリ内のすべてのファイルの概要と予想される結果が追加されます。

sudo bash -c 'echo $(tail -n 1 /etc/crontab) > /path/to/file'

なぜこのコマンドは余分なデータを生成したのですか?



3
echoここで何をしてるの?次も検討してくださいtail -n 1 /etc/crontab | sudo tee /path/to/file >/dev/null
ctrl-alt-delor

回答:


22

crontab行には*、「いつでも」を示す1つ以上のアスタリスクが含まれています。その行がコマンド置換から置換されると、結果は次のようになります

echo * * * * * cmd > /path/to/file

しながら、最もさらに拡張コマンド置換の出力に適用されていない、パス名の拡張がある(フィールド分割のように)

コマンド置換の結果は、チルド拡張、パラメーター拡張、コマンド置換、または算術拡張のために処理されません。コマンドの置換が二重引用符内で発生した場合、フィールドの分割とパス名の展開は、置換の結果に対して実行されません。

パス名の展開は*.txt、一致するファイル名(グロビング)のリストになり、*すべてに一致します。最終結果は*、crontab行のすべてに対してリストされている作業ディレクトリ内のすべての(非表示ではない)ファイル名を取得することです。


投稿したコードがより複雑なコマンドの代表である場合は、展開を引用することでこれを修正できます。

sudo bash -c 'echo "$(tail -n 1 /etc/crontab)" > /path/to/file'

しかし、もっと簡単に言えば、echo完全に失うだけです。

sudo bash -c 'tail -n 1 /etc/crontab > /path/to/file'

これはあなたが望むことをするはずであり、それも同様に単純です(他の唯一の重要な違いは、このバージョンでは本来なら発生するはずだったフィールド分割が省略されるため、スペースのランが折りたたまれないことです)。


5
/ etc / crontabはほとんどの場合誰でも読み取り可能であるため、すべての「bash -c」の手口は実際には不要です tail -n -1 /etc/crontab | sudo tee /path/to/file。スーパーユーザー権限を必要とするファイルに出力をリダイレクトするときに、最もエラーが発生しにくいことがわかっているイディオムです。
ベース

5

これらのファイルを含むディレクトリを考えてみましょう:

$ ls
crontab  file1  file2  file3
$ cat crontab
f*

次に、tailコマンドを実行してみましょう。

$ tail -n 1 crontab
f*

上記は最後の行でcrontabあり、これは私たちが期待するものです。しかしながら:

$ echo $(tail -n 1 crontab)
file1 file2 file3

二重引用符はこの問題を排除します:

$ echo "$(tail -n 1 crontab)"
f*

二重引用符がないと、コマンド置換の結果はシェルによって展開されます。展開の1つはパス名展開です。上記の場合、これは、f*で始まるすべてのファイル名に一致するように展開されることを意味しますf

シェル展開を明示的に必要としない限り、すべてのシェル変数やコマンド置換を二重引用符で囲みます。


4

グロビングシェルメカニズムは*ローカルファイルに展開されます。

crontabの行には*、あらゆるプレースホルダーが含まれている可能性があります。

たとえば、crontabのこの行は日曜日の午前7時47分に実行され、最初の星は任意の日、2番目は任意の月を意味します。

47  7 * * 0 /run/on/sunday

その後、あなたtailは発行します

echo 47  7 * * 0 /run/on/sunday

*ローカルファイルに展開されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.