폴더에서 실행되는 셸 기능이 있습니다(제 경우에는 *.eps` 파일을 찾아서 빈 테두리 없이 pdf로 변환합니다). 다음 함수로 이를 추상화해 보겠습니다.
function do_here() {
echo $(pwd)
}
ROOT_PATH
나는 루트 경로가 주어진 디렉터리와 경로를 반복 하고 do_here
각 리프에서 작업하는 현명한 방법을 찾고 있습니다 . 상징적인 나뭇잎이 있을 수 있지만 현재로서는 이 요구 사항이 플러스인 것 같습니다.
이유는 다음과 같습니다.
ROOT_PATH
디렉토리를 탐색하려면 별명을 사용하십시오to_path
.- 달리기
cd $to_path
; - 달리기
do_here
; - 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