나는 한 디렉토리에서 다른 디렉토리로 파일을 복사하기 위해 SO의 여러 스레드를 따라갔습니다. 나는 내 목적을 위해 inotifywait를 사용하고 있으며 하나의 시나리오를 제외한 모든 시나리오에서 완벽하게 작동합니다. 또한 나는 원하지 않는 DOT 접두사(예: .tmp.swp)로 시작하는 파일을 복사합니다.
이것을 시도했지만 -json
접미사가 붙은 파일도 복사되지 않았습니다. 나는 .tmp.abcd-json
복사되고 싶지 않습니다 . &&
다음을 포함한 모든 항목을 복사한 후 수표를 제거 하면 .tmp.abcd-json
:
다음은 디렉토리의 일부 내용입니다. 이는 .tmp
필수는 아니지만 항상 로 시작한다고 보장되는 것은 아닙니다 . 무시해야 하는 접두사로 무작위로 시작하는 .tmp
다른 파일도 본 적이 있습니다 ..
abcd-json
.tmp.abcd-json
#!/bin/sh
dir=/var/lib/docker/containers
target=/var/log/splunkf
inotifywait -m -r "$dir" --format '%w%f' -e create -e modify \
| while read file;
do
if [[ $file == "-json"* ]] && [[ $file != "."* ]];
then
echo Copying $file to $target
cp -- "$file" "$target";
else
echo NOT Copying $file to $target
fi
done
답변1
RegEx
파일을 일치시킬 수 있습니다아니요dot
귀하의 상황부터 시작하여 if
:
while read file;
do
f="$(basename -- $file)"
if ! [[ "$f" =~ ^\. ]];
then
echo Copying $file to $target
cp -- "$file" "$target";
else
echo NOT Copying $file to $target
fi
답변2
코드의 주요 문제는 에 없습니다 [[ ... ]]
. 실제로 얻은 문자열은 시작 부분에 디렉터리 경로가 포함된 경로 이름입니다. 즉, 패턴은 $file
점으로 시작하는 경우 .*
에만 디렉터리 경로와 일치합니다 .$dir
/bin/sh
또한 with 대신을 사용하여 스크립트를 실행하는 것으로 나타나 므로 테스트가 bash
반드시 작동할 것이라고 기대할 수는 없습니다 .[[ ... ]]
일치하는 파일 이름 패턴을 제외하려면 다음을 inotifywait
사용하십시오 --exclude 'PATTERN'
.
inotifywait -m -r --format '%w%f' -e create -e modify \
--exclude '/\.[^/]*$' "$dir"
여기에 사용된 패턴은 --exclude
점으로 시작하는 파일 이름으로 끝나는 모든 경로 이름과 일치합니다. 이러한 내용은 보고되지 않습니다 inotifywait
.
--exclude
with 를 사용하면 inotifywait
코드가 다음으로 축소됩니다.
#!/bin/sh
dir=/var/lib/docker/containers
target=/var/log/splunkf
inotifywait -m -r --format '%w%f' -e create -e modify \
--exclude '/\.[^/]*$' "$dir" |
xargs -I {} cp -- {} "$target"
이것은 분명히 파일 이름에 개행 문자가 포함되어 있지 않다고 가정합니다.
bash
명시적인 테스트 및 진단 출력이 있는 루프를 사용하려면 다음을 사용할 수 있습니다.
#!/bin/bash
dir=/var/lib/docker/containers
target=/var/log/splunkf
inotifywait -m -r --format '%w%f' -e create -e modify "$dir" |
while IFS= read -r pathname; do
if [[ ${pathname##*/} == .* ]]; then
printf 'Not copying "%s"\n' "$pathname" >&2
else
printf 'Copying "%s" to "%s"\n' "$pathname" "$target" >&2
cp -- "$pathname" "$target"
fi
done
IFS= read -r
이는 파일 이름에서 주변 공백이 제거되는 것을 방지하고 백슬래시 시퀀스를 해석하는 것을 방지하기 위한 것입니다(참조) ."IFS=read-r-line" 이해).
그것으로 /bin/sh
당신은 할 것입니다
#!/bin/sh
dir=/var/lib/docker/containers
target=/var/log/splunkf
inotifywait -m -r --format '%w%f' -e create -e modify "$dir" |
while IFS= read -r pathname; do
case ${pathname##*/} in
.*)
printf 'Not copying "%s"\n' "$pathname" >&2
;;
*)
printf 'Copying "%s" to "%s"\n' "$pathname" "$target" >&2
cp -- "$pathname" "$target"
esac
done