Bashの変数に基づいて条件付きで出力をファイルにリダイレクトする方法

Bashの変数に基づいて条件付きで出力をファイルにリダイレクトする方法

コメントを評価するためにevalコマンドを使用しようとしています。これが正しいアプローチかどうかはわかりません。例:

i=??(ここで私が望むのは、#次の内容について説明するものまたはスペースです)

somecommand arg1 arg2 $(eval $i) >> file

したがって、$i値に応じて次のようにする必要があります。

somecommand arg1 arg2 # >> file「ファイルとして印刷しない」から始めます。

または

somecommand arg1 arg2 >> file「ファイルで印刷」で始まる

より明確に説明するために、サンプルスクリプトは次のとおりです。

i=true

somecommand arg1 arg2 >> file1
[some code]
somecommand arg1 arg2 >> file2
[some code]
somecommand arg1 arg2 >> file3
[some code]
And so on...

$itrueの場合にのみ出力をファイルに印刷したいと思います。または、最初に試したとおりにeval$ iをコメントアウトし、「ファイルとして出力」フラグメントをコメントアウトします。

私はこれを行うよりもエレガントな方法があると思うので尋ねます。

if $i
then
   somecommand arg1 arg2 >> file3
else
   somecommand arg1 arg2
fi

ベストアンサー1

いつでも次のことができます。

unset -v log
# or
log=true
([ -z "$log" ] || exec >> file1; somecommand arg1 arg2)
([ -z "$log" ] || exec >> file2; somecommand arg1 arg2)

または:

if [ -n "$log" ]; then
  exec 3>> file1 4>> file2
else
  exec 3>&1 4>&1
fi
somecommand arg1 arg2 >&3
somecommand arg1 arg2 >&4

または:

log() {
  local output="$1"; shift
  if [ -n "$output" ]; then
    "$@" >> "$output"
  else
    "$@" 
  fi
}

log "${log+file1}" somecommand arg1 arg2
log "${log+file2}" somecommand arg1 arg2

または(コード挿入の脆弱性を避けるために、渡されたデータが動的ではevalないことを確認してください。したがって拡張が発生しない場合は、下に単一引用符を使用してください):

eval ${log+'>> file1'} 'somecommand arg1 arg2'
eval ${log+'>> file2'} 'somecommand arg1 arg2'

そしてzsh

if (($+log)); then
  alias -g 'log?=>>'
else
  alias -g 'log?=#'
fi

somecommand arg1 arg2 log? file1
somecommand arg1 arg2 log? file2

>>または(この種の条件付きロギング以外の目的で使用する予定がない場合):

(($+log)) || alias -g '>>=#'

somecommand arg1 arg2 >> file1
somecommand arg1 arg2 >> file2

bashいいえalias -g、このようなエイリアスを使用することはできませんが、リダイレクトを初めて移動すると>>単純なesを使用できます。alias

shopt -s expand_aliases
skip_one() { shift; "$@"; }
if [[ -v log ]]; then
  alias 'log?=>>'
else
  alias 'log?=skip_one'
fi

log? file1 somecommand arg1 arg2
log? file2 somecommand arg1 arg2

おすすめ記事