"*"를 지정하지 않으면 캐시 디렉토리가 삭제되는 이유는 무엇입니까?

"*"를 지정하지 않으면 캐시 디렉토리가 삭제되는 이유는 무엇입니까?

저는 ZSH를 기본 셸로 사용하고 그 위에 OhMyZsh를 사용합니다. 때로는 일부 파일을 삭제하고 일부 권한/소유권을 재설정해야 하므로 해당 별칭을 사용합니다. PHP/Symfony 프로젝트가 있다고 가정해 보겠습니다 /home/parallels/Development/prj1. 아래 스크립트를 사용하면 실행할 수 있지만 fixperms prj1...

  • 스크립트를 한 번 실행하고 내용을 삭제하면 $CURRENT_PROJECT/$PROJECT_CACHE다음 오류가 발생합니다.
fixperms:4: no matches found: /home/parallels/Development/prj1/framework/var/cache/*
  • *끝 부분을 삭제하면 원하지 않는 폴더도 $CURRENT_PROJECT/$PROJECT_CACHE/*삭제됩니다.cache

  • 파일은 dev.log절대 삭제되지 않습니다

내가 여기서 무엇을 놓치고 있는 걸까요?

PROJECT=framework
PROJECT_VAR=$PROJECT/var
PROJECT_CACHE=$PROJECT_VAR/cache
PROJECT_LOG=var/log/dev.log

fixperms () {
  if [ -n "$1" ]; then
    CURRENT_PROJECT=$HOME/Development/"$1"

    cd $CURRENT_PROJECT && sudo rm -rf $CURRENT_PROJECT/$PROJECT_CACHE/* && sudo rm -rf $CURRENT_PROJECT/$PROJECT_LOG && sudo chown -R "$(whoami)":root $CURRENT_PROJECT && sudo chmod -R 777 $CURRENT_PROJECT/$PROJECT_VAR
  else
    echo "Missing project param."
  fi
}

참고: 저는 bash/shell 스크립팅 전문가가 아니므로 어떤 개선이라도 환영하며 미리 감사드립니다.

답변1

모든 작업을 연결하면 &&그 중 하나가 실패하면 작업이 중단되고 해당 줄 이후의 작업은 실행되지 않습니다. 이것이 의도적인 것인지 아닌지는 확실하지 않습니다.

예를 들면 다음과 같습니다.

echo A && false && echo B
echo A && true && echo B

따라서 dev.log항목 캐시가 실패해도 삭제되지 않는 이유는 무엇입니까? 이 줄 rm이후의 내용은 실행되지 않습니다.rm -rf $CURRENT_PROJECT/$PROJECT_CACHE/*

zsh기본적으로 꺼져 있으므로 nullglob실패 *합니다.


그래도;

디렉토리가 비어 있는지 먼저 확인한 다음 나중에 확인할 수 있습니다 rm. 가장 쉬운 방법은 간단히 삭제하고 다시 만드는 것입니다.

setopt nullglob아니면 나중에 선택하셔도 됩니다 unsetopt nullglob.

기타 참고사항:

대문자 변수를 사용하는 이유가 있을 수 있지만 가능하면 사용하지 않는 것이 가장 좋습니다. 환경 변수, 내장 함수 등으로 인해 충돌이 발생할 수 있습니다.

더 많이 인용해야합니다.

나는 $project_log그것이 파일이라고 가정하고 있다면 -r그것은 쓸모가 없습니다.

echo/ printf오류가 발생했습니다 stderr.

project=framework
project_var=$project/var
project_cache=$project_var/cache
project_log=var/log/dev.log

fixperms () {
    if [ -n "$1" ]; then
        current_project="$HOME/Development/$1"

        # Change to project directory. Exit if it fails.
        # The shell should give descriptive error.
        pushd "$current_project" || exit 1

        [ -e "./$project_cache/" ] && sudo rm -r "./$project_cache/"
        sudo mkdir "./$project_cache"

        [ -e "./$project_log" ] && sudo rm "./$project_log"

        sudo chown -R "$(whoami):root" .

        sudo chmod -R 777 "./$project_var"
        # Restore directory we started from
        popd
    else
        printf 'fixperms(): Missing argument: project\n' >&2
    fi
}

return 1대신 원하는 것은 exit 1전적으로 기능을 사용하는 방법에 따라 다릅니다.

어쨌든, 존재 여부를 확인하면 -f삭제합니다.rm

답변2

sudo rm -rf $CURRENT_PROJECT/$PROJECT_CACHE/*

명령이 실행되는 방법은 다음과 같습니다(중요한 부분만 언급함).

  1. 쉘은 마지막 인수의 변수를 확장합니다. 밝혀지다 /home/parallels/Development/prj1/framework/var/cache/*.
  2. 마지막 매개변수에는 와일드카드 패턴이 포함되어 있으므로 패턴이 파일과 일치하는지 확인합니다. 귀하의 계정에는 나열된 파일에 대한 권한이 없으므로 /home/parallels/Development/prj1/framework/var/cache패턴은 어떤 파일과도 일치하지 않습니다(셸은 "일치하는 파일이 없는지 확인할 수 있습니다"와 "일치하는 파일이 있는지 확인할 수 없습니다"를 구별할 수 없습니다). 어떤 파일과도 일치하지 않는 와일드카드 패턴은 유지됩니다.
  3. 쉘은 프로그램을 실행하기 위해 매개 변수 sudo를 사용합니다 .rm-rf/home/parallels/Development/prj1/framework/var/cache/*
  4. sudorm매개변수를 사용 -rf하고 실행합니다 /home/parallels/Development/prj1/framework/var/cache/*.
  5. rm지정된 파일을 삭제합니다. 즉, *라는 디렉터리에 파일이 있으면 /home/parallels/Development/prj1/framework/var/cache해당 파일이 삭제됩니다( *디렉토리인 경우 해당 내용이 반복적으로 삭제됩니다).

와일드카드 확장(또는 삭제할 파일을 열거하는 데 사용되는 모든 방법)을 수행하려면 디렉터리에 대한 읽기 권한이 있는 셸을 준비해야 합니다. 이는 sudo를 호출하는 셸이 아니라 sudo에서 실행되는 셸에서 와일드카드 확장이 발생해야 함을 의미합니다. 예를 들어:

sudo sh -c 'rm -rf "$0"/*' "$CURRENT_PROJECT/$PROJECT_CACHE"

크기 조정 시 주의 사항을 참고하시기 바랍니다. sudo sh -c 'rm -rf $CURRENT_PROJECT/$PROJECT_CACHE/*'변수가 내부 셸에 정의되어 있지 않기 때문에 작동하지 않습니다(실행되지만 rm -rf //*시도해야 할 것은 아닙니다). sudo sh -c "rm -rf $CURRENT_PROJECT/$PROJECT_CACHE/*"이는 관련된 변수 값에 공백과 같은 문자가 포함되지 않은 경우에만 작동합니다. 이러한 값은 파일 이름이 아닌 쉘 코드 조각으로 해석되기 때문입니다.

알아채다위 명령을 실행하지 않는 것이 좋습니다., 취약하기 때문입니다. 경로가 예상한 것과 정확히 일치하지 않으면 결국 시스템의 모든 항목이 삭제될 수 있으며 명령이 루트로 실행되므로 이는 매우 나쁠 수 있습니다. 대신 필요한 권한이 있는 경우에만 명령을 실행해야 합니다.

sudo -u parallelsowner sh -c 'rm -rf "$0"/*' "$CURRENT_PROJECT/$PROJECT_CACHE"

또는

sudo -g parallelsgroup sh -c 'rm -rf "$0"/*' "$CURRENT_PROJECT/$PROJECT_CACHE"

parallelsowner문제의 디렉터리와 해당 하위 디렉터리를 소유한 사용자 또는 parallelsgroup디렉터리와 모든 하위 디렉터리에 대한 쓰기 권한이 있는 그룹은 어디에 있습니까?

관련 정보