모든 디렉토리로 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 {} \;

execdir와 exec같지만 작업 디렉토리는 다릅니다.

   -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 {} \;당신은 할 필요가 없습니다 cat에 wget가지고있는 -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.