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

관련 정보