다음과 같은 작업을 수행하는 bash 스크립트가 있습니다.
for src in $(find -H "$DOTFILES_ROOT" -maxdepth 2 -name '*.sym' -not -path '*.git*')
do
dst="$HOME/$(basename "${src%.*}")"
link_file "$src" "$dst"
done
내 스크립트에서 shellcheck를 실행했는데 결과가 반환되었습니다.
For loops over find output are fragile. Use find -exec or a while read loop.
나는 그것을 읽고 이해했으며 그것은 나에게 이해가 되었습니다.
find -H "$(pwd)" -maxdepth 2 -name '*.sym' -not -path '*.git*' -exec echo {} \;
하지만 for 루프에서 변수를 사용하여 작동하게 만드는 방법을 잘 모르겠습니다.
답변1
루프의 변수는 및 for
입니다 . 루프에서 파일에 지정된 경로 이름 에서 계산 됩니다 .src
dst
src
find
dst
src
루프는 find -exec
다음과 같은 명령으로 변환될 수 있습니다.
find -H "$DOTFILES_ROOT" -maxdepth 2 -type d -name '.git' -prune -o \
-type f -name '*.sym' -exec sh -c '
link_file "$1" "$HOME/$( basename "${1%.*}" )"' sh {} ';'
목차를 -not -path '*.git*'
볼 계획이 없다고 가정합니다 . .git
이는 -type d -name '.git' -prune
위와 동일한 명령이지만 이러한 디렉터리로의 이동도 중지합니다 -prune
.find
.git
디렉토리를 지우면 .sym
파일 찾기를 시작합니다. 하나가 발견되면 루프의 명령이 실행됩니다. 명령은 sh -c
(인수 대체를 전달하고 몇 가지 멋진 작업을 수행할 수 있도록)을 통해 실행되며 basename
발견된 파일의 경로 이름은 내부적으로 사용할 수 있습니다 $1
.
다음과 같이 작성한 대로 루프를 (거의) 병합할 수도 있습니다.
find -H "$DOTFILES_ROOT" -maxdepth 2 -type d -name '.git' -prune -o \
-type f -name '*.sym' -exec sh -c '
for src do
dst="$HOME/$( basename "${src%.*}" )"
link_file "$src" "$dst"
done' sh {} +
이 경우 sh -c
스크립트에는 단일 경로 이름이 아니라 여러 경로 이름이 제공되므로( +
끝에 있는 경로 로 인해 -exec
) 해당 경로 이름을 반복하여 작업을 수행합니다.
관련된: