서브 쉘없이 여러 조건이 없다면 bash? 작업 코드를 사용할

쉘 if 문에서 여러 조건을 결합하고 조합을 무효화하고 싶습니다. 간단한 조건 조합을 위해 다음 작업 코드가 있습니다.

if [ -f file1 ] && [ -f file2 ] && [ -f file3 ] ; then
  # do stuff with the files
fi

이것은 잘 작동합니다. 그것을 부정하고 싶다면 다음 작업 코드를 사용할 수 있습니다.

if ! ( [ -f file1 ] && [ -f file2 ] && [ -f file3 ] ) ; then
  echo "Error: You done goofed."
  exit 1
fi
# do stuff with the files

이것은 예상대로 작동합니다. 그러나 괄호가 실제로 무엇을하는지 모르겠습니다. 내가 원하는 단지 그룹화를 사용하지만 실제로 서브 쉘을 산란한다? (어떻게 알 수 있습니까?) 그렇다면 서브 쉘을 생성하지 않고 조건을 그룹화하는 방법이 있습니까?



답변

{ list;}대신에 사용해야 합니다 (list):

if ! { [ -f file1 ] && [ -f file2 ] && [ -f file3 ]; }; then
  : do something
fi

둘 다 그룹화 명령 이지만 { list;}현재 쉘 환경에서 명령을 실행합니다.

는 그 주 ;{ list;}에서 목록 구분하기 위해 필요한 }역 단어를, 당신은뿐만 아니라 다른 구분 기호를 사용할 수 있습니다. 이후의 공백 (또는 다른 구분 기호) {도 필요합니다.


답변

원하는 test기능을 전적으로 사용할 수 있습니다 . 의 맨 페이지에서 test:

 ! expression  True if expression is false.
 expression1 -a expression2
               True if both expression1 and expression2 are true.
 expression1 -o expression2
               True if either expression1 or expression2 are true.
 (expression)  True if expression is true.

따라서 상태는 다음과 같습니다.

if [ -f file1 -a -f file2 -a -f file3 ] ; then
    # do stuff with the files
fi

이스케이프 처리 된 괄호를 부정하는 경우 :

if [ ! \( -f file1 -a -f file2 -a -f file3 \) ] ; then
    echo "Error: You done goofed."
    exit 1
fi
# do stuff with the files

답변

이식 쉘에서 복잡한 조건을 부정, 당신도 적용해야합니다 드 모건의 법칙 과 안쪽 끝까지 부정을 눌러 [통화 …

if [ ! -f file1 ] || [ ! -f file2 ] || [ ! -f file3 ]
then
    # do stuff
fi

… 또는 사용해야합니다 then :; else

if [ -f file1 ] && [ -f file2 ] && [ -f file3 ]
then :
else
  # do stuff
fi

if ! command휴대 할 수 없으며 둘 다 아닙니다 [[.

완전한 이식성이 필요 하지 않다면 쉘 스크립트를 작성하지 마십시오 . 당신은 실제로 당신 보다 무작위로 선택된 유닉스 에서 찾을 가능성 이 큽니다 ./usr/bin/perlbash


답변

다른 사람들은 {복합 명령 ;}그룹화에 주목 했지만 세트 에서 동일한 테스트를 수행하는 경우 다른 종류를 사용하려고 할 수 있습니다.

if  ! for f in file1 file2 file3
      do  [ -f "$f" ] || ! break
      done
then  : do stuff
fi

… 다른 곳에서 시연되는 것처럼 { :;}복합 명령 중첩과 관련된 어려움은 없습니다 …

위의 (일반적으로) 일반 파일을 테스트 합니다. 당신은 단지를 찾는 경우에 기존 , 읽을 디렉토리 수없는 파일 :

if  ! for f in file1 file2 file3
      do  [ ! -d "$f" ] &&
          [   -r "$f" ] || ! break
      done
then  : do stuff
fi

디렉토리인지 아닌지 신경 쓰지 않는다면 :

if  ! command <file1 <file2 <file3
then  : do stuff
fi

… 어떤을위한 작품 읽기 , 접근 파일,하지만 가능성이 w 인 / 아웃 작가 FIFO를 위해 중단됩니다.


답변

이것은 주요 질문에 대한 완전한 답변은 아니지만 주석에서 복합 테스트 (읽기 가능한 파일)를 언급 한 것으로 나타났습니다. 예를 들어

if [ -f file1 ] && [ -r file1 ] && [ -f file2 ] && [ -r file2 ] && [ -f file3 ] && [ -r file3 ]

쉘 함수를 정의하여 이것을 조금 강화할 수 있습니다. 예를 들어

readable_file()
{
    [ -f "$1" ]  &&  [ -r "$1" ]
}

[ $# = 1 ]맛을 내기 위해 오류 처리를 추가하십시오 (예 :). 위의 첫 번째 if진술은 이제

if readable_file file1  &&  readable_file file2  &&  readable_file file3

함수의 이름을 줄여서 더 단축시킬 수 있습니다. 마찬가지로 함수에 부정을 정의 not_readable_file()(또는 nrf간단히)하고 포함 할 수 있습니다.


답변

중괄호 테스트 내에서 무효화하여 원래 코드를 재사용 할 수도 있습니다.

if [[ ! -f file1 ]] || [[ ! -f file2 ]] || [[ ! -f file3 ]] ; then
  # do stuff with the files
fi

답변

그룹화를 위해서만 사용하고 싶지만 실제로 서브 쉘을 생성합니까? (어떻게 알 수 있습니까?)

예,의 명령 (...)은 서브 쉘에서 실행됩니다.

서브 쉘에 있는지 테스트하기 위해 현재 쉘의 PID와 대화식 쉘의 PID를 비교할 수 있습니다.

echo $BASHPID; (echo $BASHPID); 

괄호가 서브 쉘을 생성하고 중괄호가 생성되지 않음을 보여주는 출력 예 :

$ echo $BASHPID; (echo $BASHPID); { echo $BASHPID;}
50827
50843
50827
$