파일 이름 절대 경로 배열에서 파일 이름을 얻는 방법

파일 이름 절대 경로 배열에서 파일 이름을 얻는 방법

/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반복할 때마다 인수 목록이 짧아집니다.

관련 정보