/tmp 디렉토리에서 파일 이름을 제거해야 하는 쉘 스크립트가 있습니다. 파일 이름은 내 스크립트에 전달된 파일 이름 목록에서 감지되어야 합니다.
./deletetmpfiles.sh /var/moht/test1.pdf /var/shif/log/test4.pdf
원하는 수의 파일을 매개변수로 deletetmpfiles.sh
스크립트에 전달할 수 있습니다.
위의 예를 고려하십시오.
내 스크립트는 /tmp/test1.pdf
&를 제거해야 합니다./tmp/test4.pdf
아래는 내가 시도한 것입니다.
echo "Deleting the following files as they got printed: $@"
cd /home/system/bey.de/invoices/send4print
if [ $? -eq 0 ]; then
echo "Deleting the following on the server: $@"
echo "rm -f /tmp/$(basename $@)"
rm -f /tmp/$(basename $@)
fi
그러나 /tmp의 첫 번째 파일(예: /tmp/test1.pdf)만 삭제되고 나머지 파일은 삭제되지 않습니다.
뭔가 제안해주실 수 있나요?
답변1
basename
여러 파일을 처리하지 않습니다.
이름
basename - strip directory and suffix from filenames
요약
basename NAME [SUFFIX] basename OPTION...NAME...
-a
이 옵션을 사용 하지 않는 경우 (GNU Coreutils):
-a, --multiple support multiple arguments and treat each as a NAME
그러나 파일 이름에 개행 문자가 있으면 중단됩니다.
basename -a
매개변수가 새 줄과 함께 반환되므로 명령이 실패합니다.
basename "$@"
foo.pdf
bar.pdf
rm
전달된 인수가 줄 바꿈으로 구분되므로 명령이 중단됩니다 .
이 코드는 분명히 문제를 해결했습니다.
rm $(echo "$(basename -a "$@")")
하지만 그 효과에 대해서는 잘 모르겠습니다.
그런 다음 매개변수를 반복할 수 있습니다.
for i in "$@"; do
echo "rm -f /tmp/$(basename "$i")"
rm -f "/tmp/$(basename "$i")"
done
공백이 있는 이름을 처리하려면 스크립트에 전달할 때 적절하게 이스케이프 처리해야 합니다.
$ script.sh "foo bar.pdf"
또는
$ script.sh foo\ bar.pdf
답변2
더 복잡한 내용으로 넘어가기 전에 탄탄한 기본 지식을 갖추는 것이 좋습니다.
일반적으로 주어진 작업을 수행하는 방법은 더 많습니다.
귀하의 예에 대한 기본적인 질문은 " $@
정확히 무엇을 나타내는가?" 입니다.
대답은 다음과 같습니다: "모든 명령줄 인수는 별도의 별도 문자열입니다."(Robbins 및 Beebe: Classic Shell Scripting)
매개변수의 모든 개별 멤버를 처리하려면 루프가 필요합니다.
변형 1:
for file in "$@" ; do
echo "Deleting the following on the server: $file"
file=$(basename $file)
echo "rm -f /tmp/$file"
rm -f /tmp/$file
done
변형 2:
until [ $# = 0 ]; do
echo "Deleting the following on the server: $file"
file=$(basename $file)
echo "rm -f /tmp/$file"
rm -f /tmp/$file
shift
done
변형 2에서는 shift
반복할 때마다 인수 목록이 짧아집니다.