zsh에서 여러 디렉터리를 나타내기 위해 와일드카드 문자와 함께 'rm'을 사용할 때 빈 디렉터리를 무시하는 방법은 무엇입니까?

zsh에서 여러 디렉터리를 나타내기 위해 와일드카드 문자와 함께 'rm'을 사용할 때 빈 디렉터리를 무시하는 방법은 무엇입니까?

2개 이상의 하위 디렉터리에 있는 모든 파일을 삭제하려고 하는데 zsh디렉터리가 비어 있으면 다음 디렉터리가 무시되고 파일이 유지됩니다.

예:

$ mkdir dir1
$ mkdir dir2
$ touch dir2/blah

# avoid the zsh safety prompt; this may not be necessary for this
# example, just for ease of use here
$ setopt rm_star_silent
$ rm -r dir1/* dir2/*
zsh: no matches found: dir1/*
$ ls dir2
blah

rmBash에서는 이미 비어 있는 디렉터리가 진행을 중단하지 않고 dir2삭제 dir2/blah됩니다.

이 함수는 무엇이며 에서와 같이 동작하게 zsh하는 방법이 있습니까 ?rmbash

답변1

bash와 달리 zsh기본적으로 파일 이름 생성 패턴과 일치하는 항목이 없으면 오류가 보고됩니다. 이 동작은 전체적으로 또는 모드별로 변경할 수 있습니다.

NULL_GLOB전역 불일치 패턴으로 인한 오류 메시지를 방지하려면 다음 옵션 중 하나를 설정할 수 있습니다 CSH_NULL_GLOB.

  • setopt nullglob
    

    패턴에 일치하는 항목이 없으면 매개변수 목록에서 제거됩니다. 오류 메시지가 인쇄되지 않습니다. 귀하의 예에서

    rm dir1/* dir2/*
    

    그냥 확장됩니다

    rm dir2/blah
    
  • setopt cshnullglob
    

    또한 일치하지 않는 패턴을 제거하고 일치하는 패턴이 없으면 오류 메시지를 인쇄하지 않습니다.

단일 패턴에 대한 오류 메시지를 방지하려면 이 패턴에 대해 옵션이 활성화된 N것처럼 동작하는 glob 한정자를 사용할 수 있습니다 .NULL_GLOB

rm dir1/*(N) dir2/*(N)

이는 다음으로도 확장될 예정입니다.

rm dir2/blah

답변2

가장 좋은 방법은 두 디렉터리의 파일과 일치하는 단일 글로브로 만드는 것입니다.

rm (dir1|dir2)/*

이렇게 하면 파일을 찾을 수 없는 경우에도 명령이 실행되지 않습니다.

dir1, dir2포함할 수 없으므로 주의해 주십시오 /.

이러한 경우 다음을 수행할 수 있습니다.

files=(foo/bar/*(N) bar/baz/*(N))
if ((#files)); then
  rm $files
else
  echo >&2 No matching file
fi

또는 cshnullglobcsh 또는 Bourne sh의 이전 동작을 가져오는 데 사용됩니다. 이는 bash일치하지 않는 전역 개체가 명령에 전달되는 가짜(IMO) 동작으로 되돌리는 것보다 낫습니다 . 다음을 수행할 수 있습니다.

set +o nomatch

답변3

좋은 설명은 여기에서 찾을 수 있습니다.

https://superuser.com/questions/584249/using-wildcards-in-commands-with-zsh

주요 사항은 다음과 같습니다.

By default, ZSH will generate the filenames and throw an error before executing the command if it founds no matches.

빈 디렉터리에서는 일치 항목이 생성되지 않으므로 오류가 발생합니다. 답변에서 알 수 있듯이 다음을 수행할 수 있습니다.

  1. 매개변수를 따옴표로 묶거나(예 rm -r "dir1/*" "dir2/*": )
  2. unsetopt nomatch파일에 설정 .zshrc하거나
  3. 명령에 환경 변수를 사용할 수 있습니다 noglob(예 noglob rm -r dir1/* dir2/*: )

관련 정보