`..`가 아닌 도트 파일로 확장되는 셸 파일 이름 패턴?


13

최근에 예기치 않은 방식으로 확장 된 쉘 패턴으로 인해 약간의 사고가 발생했습니다. /root디렉토리 에서 많은 도트 파일의 소유자를 변경하고 싶었습니다.

chown -R root .*

당연히 .*확장 ..은 약간의 재앙이었습니다.

내가 알고있는 bash몇 가지 쉘 옵션을 조정하여 변경할 수 있습니다이 동작하지만, 기본 설정 디렉토리에있는 모든 점 파일을 확장하지만로하는 어떤 패턴이 ...?

답변:


20

Bash, ksh 및 zsh는 더 나은 솔루션을 제공하지만이 답변에서는 POSIX 셸을 사용합니다.

이 패턴 .[!.]*은 점으로 시작하고 그 뒤에 점이 아닌 문자가 오는 모든 파일과 일치합니다. (주 [^.]일부 포탄에 의해 지원 아니지만, 와일드 카드 패턴의 문자 집합 보완을위한 휴대용 구문입니다 [!.].)이 때문에 제외 .하고 .., 또한 두 개의 점으로 시작하는 파일입니다. 이 패턴 ..?*은 두 개의 점으로 시작하고 단순한 파일이 아닌 파일을 처리합니다 ...

chown -R root .[!.]* ..?*

모든 파일과 일치하도록 설정된 클래식 패턴입니다.

* .[!.]* ..?*

이 방법의 한계는 패턴 중 하나가 아무것도 일치하지 않으면 명령으로 전달된다는 것입니다. 스크립트에서 .and를 제외한 디렉토리의 모든 파일을 일치 시키려면 ..여러 가지 해결책이 있으며 모두 성가시다.

  • 사용은 * .*모든 항목을 열거하고, 제외 할 ...루프있다. 패턴 중 하나 또는 둘 모두가 일치하지 않을 수 있으므로 루프는 각 파일의 존재를 확인해야합니다. 다른 기준을 필터링 할 기회가 있습니다. 예를 들어 -h매달린 심볼릭 링크를 건너 뛰려면 테스트를 제거하십시오 .

    for x in * .*; do
      case $x in .|..) continue;; esac
      [ -e "$x" ] || [ -h "$x" ] || continue
      somecommand "$x"
    done
  • 명령이 한 번만 실행되는보다 복잡한 변형입니다. 위치 매개 변수가 지워집니다 (POSIX 쉘에는 배열이 없습니다). 이것이 문제라면 이것을 별도의 함수에 넣으십시오.

    set --
    for x in * .[!.]* ..?*; do
      case $x in .|..) continue;; esac
      [ -e "$x" ] || [ -h "$x" ] || continue
      set -- "$@" "$x"
    done
    somecommand "$@"
  • * .[!.]* ..?*삼부작을 사용하십시오 . 다시 말하지만, 하나 이상의 패턴이 아무 것도 일치하지 않을 수 있으므로 기존 파일 (매달린 심볼 링크 포함)을 확인해야합니다.

    for x in * .[!.]* ..?*; do
      [ -e "$x" ] || [ -h "$x" ] || continue
      somecommand "$x"
    done
  • * .[!.]* ..?*tryptich를 사용하고 패턴마다 한 번 씩만 명령을 실행하십시오. 명령을 한 번만 실행합니다. 위치 매개 변수가 지워지고 (POSIX 셸에는 배열이 없음) 이것이 문제인 경우 별도의 함수에 넣습니다.

    set -- *
    [ -e "$1" ] || [ -h "$1" ] || shift
    set -- .[!.]* "$@"
    [ -e "$1" ] || [ -h "$1" ] || shift
    set -- ..?* "$@"
    [ -e "$1" ] || [ -h "$1" ] || shift
    somecommand "$@"
  • 사용하십시오 find. GNU 또는 BSD find를 사용하면 옵션 -mindepth및로 재귀를 피할 수 있습니다 -maxdepth. POSIX 찾기를 사용하면 조금 까다 롭지 만 수행 할 수 있습니다. 이 형식은 파일 당 한 번이 아니라 한 번만 명령을 쉽게 실행할 수 있다는 장점이 있습니다 (그러나 보장되지는 않습니다. 결과 명령이 너무 길면 명령이 여러 배치로 실행 됨).

    find . -name . -o -exec somecommand {} + -o -type d -prune

6

모든 파일 이름에 3 자 이상 (점 포함)이 포함 된 경우 작동합니다.

chown -R root .??*

보다 강력한 솔루션을 위해 find다음 을 사용할 수 있습니다 .

find . -maxdepth 1 -name '.*' -exec chown -R root {} \;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.