FTP 서버에 로그인하고 일부 디렉토리의 이름을 바꾸는 쉘 스크립트를 만들었습니다. FTP 명령을 다음과 같은 여러 줄 문자열에 넣었습니다.
# !/bin/sh
ftp -inv $HOST << EOF
user $USER $PASSWORD
$COMMANDS
bye
EOF
$COMMANDS
줄 바꿈으로 구분된 명령을 포함합니다 . 이 접근 방식은 다음과 같은 명령을 구성할 때 작동합니다.
NL=$'\n'
COMMANDS="command one$NL"
COMMANDS+="command two$NL"
COMMANDS+="command three"
$COMMANDS
처음에는 함수 패딩을 사용해 보았지만 printf
여러 번 시도한 후에도 성공하지 못했습니다. 표현 방식
COMMANDS="$(printf "%s\n" "command one" "command two" "command three")"
명령 사이에 공백이 있는 문자열로 평가되며, 스크립트에서 FTP 명령으로 사용되는 경우 단일 라인으로 처리됩니다.
교체를 시도했는데 \n
그 \r
결과 변수가 $COMMANDS
문자열로 채워지지 않았습니다.
누군가가 더 교육을 받을 수 있을까요?제발printf
설명해주세요. 여기 기능에 문제가 있나요?
고쳐 쓰다
rsync를 통해 가까스로 목표를 달성했기 때문에 FTP 방식을 포기했는데, 왜 이런 일이 일어나는지 아직도 궁금합니다.
문제는 printf
변수에 저장하는 것입니다. 테스트 스크립트를 만들었습니다.
echo "==== printf directly"
printf "%s\n" "foo" "bar" "baz"
echo "==== stored in variable"
VAR_1=$(printf "%s\n" "foo" "bar" "baz")
echo $VAR_1
./test.sh
출력 실행
==== printf directly
foo
bar
baz
==== stored in variable
foo bar baz
설정이 IFS=$'\n'
도움이 되지 않습니다.
업데이트 2
변수를 큰따옴표로 묶으면 변수에서 여러 줄을 얻을 수 있습니다.
echo "$VAR_1"
하지만 heredoc에서 사용하면 동일한 결과를 얻을 수 없습니다.
echo `cat <<EOF
$VAR_1
"$VAR_1"
EOF`
나는 출력을 얻는다
foo bar baz "foo bar baz"
참고: heredoc의 두 변수 출력 사이에는 개행 문자조차 없습니다. 이는 나에게도 이상합니다.
답변1
따옴표를 사용하지 않으면 토큰화는 문자열을 공백(기본적으로)으로 분할하고 echo
분할된 부분을 공백과 연결합니다. 실제로 이는 개행 문자를 "먹게" 됩니다.
개선 사항을 발견했습니다
echo "$VAR_1"
이제 이 문서에 대해 동일한 작업을 수행합니다.
echo "`cat <<EOF
$VAR_1
EOF`"
echo
편집 : 먹는 개행 문자가 아니라 껍질입니다.