exec가 예상대로 작동하지 않는 경우 찾기

exec가 예상대로 작동하지 않는 경우 찾기

폴더가 있는지 확인하고 폴더가 있으면 한 가지 작업을 수행하고 없으면 다른 작업을 수행해야 합니다. 이 작업을 수행하기 위해 find를 사용하지만 올바른 방법을 찾을 수 없습니다.

find /path/to/destination -maxdepth 1 -type d -name "dir*" -exec bash -c '[[ $1 ]] && echo ok || echo "not ok"' _ {} \;

그러나 bash 부분의 부분은 구현하기에 더 새로운 것입니다. 제안 사항이 있습니까?

답변1

이 작업은 이전 조건 (and)과 일치하는 파일에 대해서만 수행 되며 -exec파일당 한 번 수행됩니다.-name 'dir*'-type d

여기에서 다음과 같은 작업을 수행할 수 있습니다 zsh.

dirs=(/path/to/destination/dir*(N/))
if (($#dirs)); then
  echo Found these dirs:
  printf ' - %s\n' $dirs
else
  echo >&2 No dir found
fi

또는 bash 버전 4.4 이상 및 find호환 가능한 GNU를 사용하는 경우( -maxdepth사용 시 이미 GNU 확장을 사용하고 있어야 함):

readarray -td '' dirs < <(
  find /path/to/destination -maxdepth 1 -type d -name "dir*" -print0)

if ((${#dirs[@]})); then
  echo Found these dirs:
  printf ' - %s\n' "${dirs[@]}"
else
  echo >&2 No dir found
fi

답변2

해당 이름 패턴과 일치하는 디렉터리가 있는지 확인하려면 find해당 디렉터리에 대한 더미 출력을 인쇄하고 출력이 비어 있는지 확인할 수 있습니다. 예를 들어:

if [[ "$(find -type d -name "dir*" -printf .)" ]] ; then
    echo "some matching directory exists"
else 
    echo "no matching directory exists"
fi

find전달할 수도 있습니다 . 명령이 출력을 생성하지 않으면 문제가 없습니다.-exec bash -c '...' _ {} \;-printf

시작된 명령의 출력을 캡처하고 이를 가상 출력과 분리해야 하는 경우 find상황은 더욱 악화됩니다 . 임시 파일이나 리디렉션 트릭이 필요합니다. 이는 somecmd일치하는 모든 디렉터리에서 실행되어야 하며 find실행 출력을 somecmd스크립트 stdout으로 보낸 다음 일치하는 항목이 있는지 알려주어야 합니다.

exec 3>&1
any=$(find -type d -name "dir*" -printf . -exec bash -c 'somecmd "$1" >&3' _ {} \; )
if [[ "$any" ]] ; then
    echo "matching directories were processed"
else 
    echo "no matching directory exists"
fi
exec 3>&-

물론 명령이 내려지면find 언제나출력을 생성하며 더미 출력이 필요하지 않습니다. 인쇄물 을 캡처하여 find비어 있는지 확인하세요.

답변3

추악하지만 bash에서는 다음과 같습니다.

(shopt -s nullglob; if ! [ -z /path/to/destination/dir*/ ] 2>&-; then  echo ok; else echo not ok; fi)

활성화되면 nullglob다음 /path/to/destination/dir*/으로 확장됩니다.

  • 일치하는 디렉터리가 없으면 아무 작업도 수행하지 않습니다. 이 경우 테스트는 -z성공하므로 부정적인 테스트는 실패합니다.
  • 또는 일치하는 모든 디렉터리 목록입니다. 이 경우:

    • 디렉터리가 하나만 있으면 -z테스트가 실패합니다.
    • -z하나의 피연산자만 필요하기 때문에 디렉터리가 여러 개 있는 경우 테스트 명령이 실패합니다.

    따라서 부정적인 테스트가 통과됩니다.

예:

$ if ! [ -z /a* ] 2>&-; then  echo ok; else echo not ok; fi
not ok
$ if ! [ -z /b* ] 2>&-; then  echo ok; else echo not ok; fi # multiple: /bin /boot 
ok
$ if ! [ -z /h* ] 2>&-; then  echo ok; else echo not ok; fi # single: /home
ok

.[[ ... ]]

관련 정보