모든 디렉토리로 cd, 해당 디렉토리의 파일에 대한 명령을 실행하고 이전의 현재 디렉토리로 돌아 가기


41

많은 단일 레벨 하위 디렉토리가있는 주어진 디렉토리에서 실행될 스크립트를 작성하려고합니다. 스크립트는 각 하위 디렉토리로 cd하고 디렉토리의 파일에서 명령을 실행 한 후 cd를 눌러 다음 디렉토리로 계속 진행합니다. 가장 좋은 방법은 무엇입니까?


1
주어진 현재 수준의 정보를 고려할 때 관련성이 없습니다 youtube-dl.
HalosGhost

답변:


83
for d in ./*/ ; do (cd "$d" && somecommand); done

12
응답자가 어떤 종류의 설명도 생략 했으므로 시도해 보겠습니다. 변수의 for d in ./*/모든 항목 ./*/(이 경우 파일 / 폴더 목록) 을 저장하는 루프를 시작 합니다 $d. do (cd "$d" && somecommand);루프의 본문을 시작합니다. 본문 안에서는 서브 쉘을 시작 하고 cdand somecommand명령을 실행 합니다. 하위 쉘이므로 상위 쉘 (이 명령을 실행하는 쉘)은 CWD 및 기타 환경 변수를 유지합니다. done루프 본체를 간단히 닫습니다.
Qix

이 방법은 디렉토리의 하위 디렉토리에 적용 for d in ./*/ ; do (cd "$d" && ls); done됩니다 : , 작동하지 않습니다. 그러나 for d in ./*/ ; do (cd "$d" && for d in ./*/ ; do (cd "$d" && ls); done ); done작동합니다. -이 예제에서 ls를 명령으로 사용.
Michael Dimmitt

-bash: cd: ./*/: No such file or directory
S. Tarık Çetin

15

가장 좋은 방법은 전혀 사용하지 않는 것입니다 cd.

find some/dir -type f -execdir somecommand {} \;

execdirexec같지만 작업 디렉토리는 다릅니다.

   -execdir command {} [;|+]
          Like   -exec,   but  the  specified  command  is  run  from  the
          subdirectory containing the matched file, which is not  normally
          the  directory  in  which  you  started  find.  This a much more
          secure  method  for  invoking  commands,  as  it   avoids   race
          conditions  during resolution of the paths to the matched files.

POSIX가 아닙니다.


이것은 별칭과 함께 작동합니까? find * /. link -type f -execdir md $ (cat .link) {} \;를 입력하면 특정 파일을 다운로드 할 수 있지만 인식하지 못합니다
뭔가 존스

@SomethingJones no는 find해당 명령을 실행하므로 별칭을 인식하지 못합니다. 무엇 md과는 .link디렉토리?
muru December

.link는 다운로드해야하는 URL이있는 텍스트 파일입니다. md는 많은 플래그가 설정되어있는 별명입니다. 별명을 인식하는 방법이 있습니까?
뭔가 Jones

특정 사용 케이스에 대한 @SomethingJones, 상품 bash: find . -type f -iname '*.link' -execdir ${BASH_ALIASES[md]} -i {} \;당신은 할 필요가 없습니다 catwget가지고있는 -i파일에서 URL 읽기에 대한 플래그. 또한 이것은 원래 질문과 다소 다릅니다 (이름이있는 파일에만 관심이있는 것 같고 .link다른 파일은 없을 수 있기 때문에).
muru December

zsh로 어떻게하는지 아십니까? 나는 당신이 나에게 무엇을 시도하고 "나쁜 대체"오류가 발생합니다. 또한 .link 파일의 내용을 어떻게 추출 할 수 있습니까? 나는이 경우에 필요하지 않다는 것을 알고 있지만 곧 나올 것이라고 상상합니다.
뭔가 Jones

2
cd -P .
for dir in ./*/
do cd -P "$dir" ||continue
   printf %s\\n "$PWD" >&2
   command && cd "$OLDPWD" || 
! break; done || ! cd - >&2

위의 명령은 서브 쉘을 수행 할 필요가 없습니다. 단지 $OLDPWD와 를 교대로하여 현재 쉘에서의 진행 상황을 추적합니다 $PWD. cd -쉘이 기본적으로 디렉토리를 변경함에 따라이 두 변수의 값을 교환 할 때 . 또한 stderr에서 작동 할 때 각 디렉토리의 이름을 인쇄합니다.

방금 두 번째로 살펴보고 오류 처리로 더 나은 작업을 수행 할 수 있다고 결정했습니다. 그것은되는이 할 수없는 말 일세를 건너 뜁니다 cd- 그리고 cdstderr에 이유에 대한 메시지를 출력 할 것이다 - 그것은 것입니다 break당신이 경우 / 0이 아닌 종료 코드 W command성공적으로 실행되지 않거나 실행이 경우 command어떻게 든 원래 디렉토리로 복귀 할 수있는 능력에 영향을 미친다 - $OLDPWD. 이 경우에도 cd -마지막을 수행하고 결과 현재 작업 디렉토리 이름을 stderr에 씁니다.


1
for D in ./*; do
    if [ -d "$D" ]; then
        cd "$D"
        run_something
        cd ..
    fi
done
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.