次のスクリプトがあります(行番号は参照にのみ使用されます)。
#!/bin/bash
1- for version in `ls -al ./atk/ | grep ^d | grep -Ev '\.$' | awk -F' ' '{print $8}'`
2- do
3- grep $version ./atk/versions #&>/dev/null <--(first ran with this comment out)
4- if [ $? -ne 0 ]
5- then
6- printf '%-15s\n' "$version"
7- fi
8- done
現状のまま実行すると、ライン1は次を画面に送信します。 (私はこれを本当に望んでおらず、stdout / stderrがに移動したいの/dev/null
ですが、これについては後で詳しく説明します。)
aaaaa--------
bbbbb |
ccccc |
ddddd |------------ wil be stored in the version variable
eeeee |
fffff |
ggggg--------
$version
行2では、以下を含む「バージョン」ファイルを探します。
12345
aaaaa
67890
ccccc
09876
fffff
$version
「versions」ファイルにない場合、$ versionsは標準出力として印刷されます。
出力は次のようになります。
bbbbb
ddddd
eeeee
ggggg
ライン1が出力をに送り/dev/null
、ライン3に出力をstdoutとstderrに送り返すにはどうすればよいですか?
奇妙なことは、3行目のコメントを削除すると/dev/null
stdoutとstderrが!にリダイレクトされますが、すべてがうまく機能することです。
私は以下を試しました:
for version in `ls -al ./atk/ | grep ^d &>/dev/null | grep -Ev '\.$' | awk -F' ' '{print $8}'` &>/dev/null
これは私が見たくないライン1の出力を抑制するだけでなく、コードを修正した後も見たいライン3の出力も抑制します。
for version in `ls -al ./atk/ | grep ^d | grep -Ev '\.$' | awk -F' ' '{print $8}'` &>/dev/null
do
exec &>/dev/tty ++++++++++++++ trying to reset stdout and stderr back to the origal setting
grep $version ./atk/versions #&>/dev/null
繰り返しますが、すべての出力をに送信するように明示的に要求すると、コメントアウトされていない3行が機能するのはなぜですか/dev/null
?
答え1
行1では、バックティック内のコマンドはそのコマンドを送信します。標準出力ループfor...
。コマンドでエラーが発生しない限り(ls
ディレクトリパスの欠落に関する苦情の表示など)、画面に何も書きません。
3行目grep
は書き込みます。標準出力、しかし。たぶん-q
自動モードフラグが欲しいかもしれません。
私はそれがおそらくより簡単に処理できると思うので、実際にやりたいことが何であるかを理解しようとしています。
for item in atk/*
do
test -d "$item" && echo "${item/*\/}" | grep -Fvf atk/versions
done
しかし、コマンド補間に逆引用符を使用することは、もはや良いコーディングスタイルとは見なされません。この構造を使用する方が良いです$( ... )
。例えばfor version in $( ls ... awk )