제공된 개수의 파일을 삭제해야 하는 스크립트는 하나의 파일만 삭제합니다.

제공된 개수의 파일을 삭제해야 하는 스크립트는 하나의 파일만 삭제합니다.

나의 매우 원시적인 쉘 스크립트는 두 개의 매개변수를 사용합니다. 첫 번째는 위치이고 두 번째는 삭제해야 하는 파일 수입니다. 무슨 이유에서인지 예시 3과 같은 매개변수를 줬는데도 파일이 한 개만 삭제되는군요. 암호:

#!/bin/bash
for i in {0..$2}
do
find $1 -type f | head -1 | xargs rm
done

고쳐 쓰다 이 코드는 어떤 이유로 두 개의 파일을 삭제하는 것 같습니다.

#!/bin/bash
for i in eval {0..$2}
do
find "$1" -type f | head -1 | xargs rm
done

답변1

우선순위의 문제입니다. 대괄호 확장 내부의 변수는 대괄호가 평가되기 때문에 해석되지 않습니다.앞으로변수가 확장됩니다. 이를 설명하려면 다음 명령을 실행하십시오.

$ var=3
$ set -x
$ echo {0..$var}
+ echo '{0..3}'
{0..3}

보시다시피 echo {0..$var}는 으로 확장되므로 echo '{0..3}'리터럴 문자열 은 예상한 것과 {0..3}다릅니다 .0 1 2 3

이 문제를 해결하는 한 가지 방법은 다음을 사용하는 것입니다 eval.

$ eval echo {0..$var}
+ eval echo '{0..3}'
++ echo 0 1 2 3
0 1 2 3

따라서 스크립트를 다음과 같이 변경할 수 있습니다.

#!/bin/bash
for i in $(eval echo {0..$2})
do
    find "$1" -type f | head -1 | xargs rm
done

그러나 이것은 위험하고 추악한 일이다. 이것이 더 좋을 것입니다:

#!/bin/bash
for((i=0;i<=$2;i++))
do
    find "$1" -type f | head -1 | xargs rm --
done

몇 가지 기본 보안 테스트가 있고 임의의 파일 이름(이름에 줄 바꿈이 포함된 파일 포함)을 처리할 수 있는 더 나은 버전(GNU 도구를 사용하는 경우)은 다음과 같습니다.

#!/bin/bash

if [[ $# -ne 2 ]]; then
  echo "We need 2 arguments!"
  exit
fi
if [[ ! $2 =~ ^[0-9]+$ ]]; then
  echo "The second argument ('$2') must be a number!"
  exit;
fi

for((i=0;i<=$2;i++))
do
  find "$1" -type f -print0 | head -z -n 1 | xargs -0 -I {} rm -- {}
done

관련 정보