나는 bash 스크립트를 가지고 있습니다 (참조여기) 하위 디렉터리에 있는 파일 목록을 파일 이름별로 정렬하는 데 사용합니다.
스크립트는 정렬된 파일을 에 추가한 hooks/pre-relevant/
다음 파일을 추가합니다.명명 된 hooks/pre-relevant
, 이름이 지정된 파일을 차례로 선택한 hooks/relevant
후 다음 함수를 hooks/relevant/
사용하여 append_hook
파일을 정렬합니다 .
hooks=()
# Run a hook script, if it's executable, with the input from this invocation
append_hook () {
if [[ -f "$1" && -x "$1" ]]; then
hooks+=("$1")
fi
}
다음 디렉토리 구조를 사용하여 테스트하고 있습니다.
testing-range/plugins/
|-- bar
| `-- hooks
| |-- irrelevant
| |-- only-one
| `-- relevant
|-- dickory
| `-- hooks
| `-- pre-relevant
|-- doc
| `-- hooks
| |-- perl-envsubst
| `-- relevant
| |-- 00
| `-- 20
|
|-- factory
| `-- hooks
| `-- relevant
`-- hickory
`-- hooks
|-- pre-relevant
| `-- 30
`-- relevant
`-- 10
이 다단계 배열 코드를 사용하여 파일을 첨부하면 다음과 같습니다.
append_numbered_hooks () {
# Gather every file into an array, prefixing each item with the
# filename of the script (its position in sort order)
local filelist=()
for hook in "$PLUSHU_ROOT"/plugins/*/hooks/"$hookname"/*; do
filelist+=("${hook##*/}/$hook")
done
# Sort the array numerically
printf '%s\0' "${filelist[@]}" | sort -nz | IFS= read -rd '' -a filelist
# Append each script in sorted order
for hookline in "${filelist[@]}"; do
append_hook "${hookline#*/}"
done
}
알겠어요거의올바른 출력:
hickory/hooks/pre-relevant/30
dickory/hooks/pre-relevant
bar/hooks/relevant
factory/hooks/relevant
doc/hooks/relevant/00
doc/hooks/relevant/20
hickory/hooks/relevant/10
그러나 이 간단한 파이프를 사용하여 파일을 추가하면 다음과 같습니다.
append_numbered_hooks () {
for hook in "$PLUSHU_ROOT"/plugins/*/hooks/"$1"/*; do
printf '%s\0' "${hook##*/}/$hook"
done | sort -nz | while IFS= read -rd '' hookline; do
append_hook "${hookline#*/}"
done
}
번호가 매겨진 파일은 "${hooks[@]}" 루프에 표시되지 않습니다.
dickory/hooks/pre-relevant
bar/hooks/relevant
factory/hooks/relevant
어떻게 되어가나요? 올바른 값은 다음과 같아야 합니다.
hickory/hooks/pre-relevant/30
dickory/hooks/pre-relevant
bar/hooks/relevant
factory/hooks/relevant
doc/hooks/relevant/00
hickory/hooks/relevant/10
doc/hooks/relevant/20
답변1
~에서http://www.gnu.org/software/bash/manual/bashref.html#Pipelines
파이프라인의 각 명령은 자체 하위 셸에서 실행됩니다.
따라서 서브셸에서 변수를 변경하고 있습니다. 이러한 변경 사항은 서브쉘이 종료되면 사라집니다.
당신은 찾을 수 있습니다프로세스 교체도움이 되는.
append_numbered_hooks () {
while IFS= read -rd '' hookline; do
append_hook "${hookline#*/}"
done < <(
for hook in "$PLUSHU_ROOT"/plugins/*/hooks/"$1"/*; do
printf '%s\0' "${hook##*/}/$hook"
done |
sort -nz
)
}