간단한 bash 스크립트가 작동하지 않습니다

간단한 bash 스크립트가 작동하지 않습니다

이 스크립트는 이름이 명령줄에서 인수로 제공되는 모든 파일을 사용자 홈 디렉터리에 복사해야 합니다. 파일이 제공되지 않은 경우 스크립트는 읽기를 사용하여 파일 이름을 요청하고 응답에 제공된 모든 파일 이름을 사용자 홈 디렉터리에 복사해야 합니다.

if [ -z $1 ]
then
    echo provide filenames
    read $FILENAMES
else
    FILENAMES="$@"
fi

echo the following filenames have been provided: $FILENAMES
for i in $FILENAMES
do
    cp $i $HOME
done

인수를 문자열로 제공하면 작동합니다. 그러나 "read $FILENAMES"로 제공하면 작동하지 않습니다.

멘토는 수업에서 동일한 솔루션을 보여주었지만 그것이 어떻게 작동하는지 보여주지 않았습니다. 여기에 이미지 설명을 입력하세요

업데이트 파일 이름을 인수로 입력한 후 빈 문자열이 제공되고 파일을 $HOME 위치에 복사하지 않았습니다.

[dmytro@oc1726036122 ~]$ cd Desktop/
[dmytro@oc1726036122 Desktop]$ . totmp 
provide filenames
one two
the following filenames have been provided:
the following filenames have been provided:
[dmytro@oc1726036122 Desktop]$

답변1

read변수를 읽는 대신 선언합니다 . 간단히 말해서 $에서 제거 read하면 됩니다.

if [ -z $1 ]
then
    echo provide filenames
    read FILENAMES
else
    FILENAMES="$@"
fi

echo the following filenames have been provided: $FILENAMES
for i in $FILENAMES
do
    cp $i $HOME
done

source편집: ( .) 명령을 사용하여 스크립트를 실행하는 것으로 확인되었습니다 .

[dmytro@oc1726036122 Desktop]$ . totmp

이 특정 스크립트에는 괜찮을 수 있지만 복잡한 스크립트에는 절대 그렇게 하지 마십시오. 그렇지 않으면 해당 스크립트의 변수나 함수를 쉘에 소스로 제공합니다. 그냥 사용bash totmp

답변2

당신을 방해하는 것 같은 문제는 read명령이 올바르지 않다는 것입니다. 전달된 인수는 변수 이름이어야 하므로 a 없이 전달되어야 합니다 $( $변수의 내용이 확장되며 해당 시점에서는 비어 있게 됩니다). 이므로 결과는 read변수 이름이 전달되지 않은 것입니다.)

read FILENAMES

첫 번째 명령줄 인수가 없는지 확인하는 데 또 다른 문제가 있습니다. 존재하지 않으면 $1아무 것도 확장하지 않고(빈 문자열이 아님) 명령에 문제를 일으킬 수 있습니다. 실제로 유효하지 않기 [때문에 이 경우 확인할 것으로 예상됩니다. 즉, 해당 변수를 인용해야 합니다.[ -z ][ -z "" ]

if [ -z "$1" ]

Bash를 사용하는 경우 를 사용할 수도 있습니다. [[ ... ]]이는 내부 명령이므로 일반적으로 더 좋습니다(이 경우 이 명령은 따옴표 없이 작동해야 하지만 따옴표를 유지해도 문제가 되지 않고 보기에도 좋습니다.)

(PS: 이 스크립트에는 잘못된 점이 훨씬 더 많습니다. 모범 사례와는 거리가 멀기 때문에 누군가가 이것을 가르치는 것을 보면 정말 소름이 끼칩니다. 불행하게도 bash를 가르치기에는 기준이 정말 낮은 것 같고 매뉴얼도 정말 복잡합니다. 실제로 잘 이해하고 계시기 때문에 제대로 배우는 방법에 대해서도 더 나은 조언이 있을지 모르겠습니다.)☹️

답변3

명령 은 read변수를 사용하지만 이미 변수 값을 참조하고 있습니다.

 #correct syntax
 read variable
 #wrong syntax
 read $variable

$variable는 값 variable이고 스크립트 시작 부분에서는 설정되지 않았거나 비어 있습니다.

관련 정보