고쳐 쓰다

고쳐 쓰다

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편집 : 먹는 개행 문자가 아니라 껍질입니다.

관련 정보