제자리에서 작동하고 결과를 출력

제자리에서 작동하고 결과를 출력

폴더에서 실행되는 셸 기능이 있습니다(제 경우에는 *.eps` 파일을 찾아서 빈 테두리 없이 pdf로 변환합니다). 다음 함수로 이를 추상화해 보겠습니다.

function do_here() {
    echo $(pwd)
}

ROOT_PATH나는 루트 경로가 주어진 디렉터리와 경로를 반복 하고 do_here각 리프에서 작업하는 현명한 방법을 찾고 있습니다 . 상징적인 나뭇잎이 있을 수 있지만 현재로서는 이 요구 사항이 플러스인 것 같습니다.

이유는 다음과 같습니다.

  1. ROOT_PATH디렉토리를 탐색하려면 별명을 사용하십시오 to_path.
  2. 달리기 cd $to_path;
  3. 달리기 do_here;
  4. 2단계로 이동합니다.

1단계에서 디렉터리 경로 목록을 가져오는 방법을 모르겠습니다.

답변1

Bash는 설정된 **경우 재귀 와일드카드 도 지원합니다 . shopt -s globstar.glob을 접미사로 사용하면 디렉토리만 가져옵니다 /. dotglob이름이 점으로 시작하는 디렉터리를 놓치지 않도록 추가되었습니다 .

예를 들어

#!/bin/bash
shopt -s globstar
shopt -s dotglob
do_here() {
    echo "working in $(pwd)...";
}
# cd ROOT_PATH
for d in **/; do (
    cd "$d"
    do_here
)
done

**쉘 작동 방식 , 즉 디렉토리 트리 내의 기호 링크와 관련하여 몇 가지 차이점이 있습니다 . 트리에 다른 디렉터리에 대한 링크가 포함되어 있으면 적어도 일부 버전의 Bash가 트리 범위를 벗어나서 이를 따릅니다. ("기호 나뭇잎"이 무슨 뜻인지 잘 모르겠어서 그게 문제인지는 모르겠습니다.)

답변2

디렉토리의 모든 파일을 얻는 것처럼 모든 디렉토리를 얻으려면 다음을 사용할 수 있습니다.와일드카드;그런 다음 루프를 사용하여 for결과를 반복하고 하위 쉘( ( commands in subshell )) 또는 pushd/ 스택 popd의 디렉토리를 시작합니다. 예를 들어:

#!/usr/bin/zsh
for directory in **/*(ND/) ; do
  print -r -u2 Working on ${directory}
  (             # do in subshell, so that `cd` doesn't affect
                # the next iteration
    cd -- "${directory}" && \
    do_here     # && : only if `cd` succeeded, do `do_here`
  ) || { 
         print -r -- "${directory} failed" >&2 | \
         logger -p user.err 
       }
done

그것을 분해하자

for directory in **/*(ND/) ; do
# ^ ^---+---^    ^  ^ ^^^  
# |     |        |  | ||\ *(/) extended glob: match directories
# |     |        |  | |\- *(N) extended glob: null glob, i.e., don't fail if
# |     |        |  | |                       nothing matches
# |     |        |  | \-- *(D) extended glob: include directories starting with 
# |     |        |  |                         ".", i.e., normally hidden dirs
# |     |        |  \---- * glob operator
# |     |        \------- **/ apply the following globbing recursively
# |     |
# |     \---------------- "loop variable": `directory` gets set to each result, 
# |                       consecutively
# |
# \---------------------- for {variable name} in {list-generating expression} :
#                         for loop

관련 정보