오늘 나는 FTP당 모든 파일을 내 대상 서버에 복사해야 하는 스크립트를 작성했습니다.
스크립트는 zsh-shell 내에서 실행되므로 올바르게 실행하려면 "sh script.sh"를 사용해야 할까요?
나는 또한 내 스크립트를https://www.shellcheck.net/, 괜찮다고 하는데 zsh-shell에서 다음 오류가 발생합니다.
upload_file: command not found
#!/bin/bash
FTP_SERVER=ftp.ip
FTP_USER=ftp.user
FTP_PASS=ftp.passwd
FTP_DESTINATION_DIR="/destination_directory"
LOCAL_SOURCE_DIR="/home/$USER/pictures/local_pictures"
function upload_file {
local file=$1
echo "Hochladen von Datei $file"
ftp -inv "$FTP_SERVER" << EOF
user $FTP_USER $FTP_PASS
binary
cd $FTP_DESTINATION_DIR
put $file
quit
EOF
}
find "$LOCAL_SOURCE_DIR" \( -name "*.jpg" -o -name "*.png" \) -exec bash -c 'upload_file "$0"' {} \;
이런 스크립트는 익숙하지 않아서...
답변1
문제는 선언한 함수가 bash
실행하는 두 번째 인스턴스에 표시되지 않는다는 것입니다 find ... -exec
.https://shellcheck.net/문제를 찾는 대신 작은따옴표로 묶인 리터럴 문자열만 보는 것도 가능합니다.
Bash 스크립트를 실행하는 데 sh
문제가 될 수도 있습니다 . 귀하의 스크립트는 비표준 선언 이외의 Bash 기능을 사용하지 않지만 function
실제로 표준 POSIX 함수 선언 구문보다 이를 선호할 이유가 없습니다. ( sh
시스템에서 Bash에 대한 심볼릭 링크인 경우 로 호출될 때 많은 Bash 전용 기능이 꺼지더라도 작동할 수 있습니다 sh
. 하지만 여전히 차이점을 이해하고 이를 사용하여 bash
Bash 스크립트를 실행해야 합니다.)
어떤 경우든 선호되는 메커니즘은 스크립트를 작성한 다음 chmod +x
해당 경로(또는 디렉토리가 사용자의 것인 경우 이름만)를 지정하여 PATH
실행하는 것입니다 . 이를 통해셰르본올바른 통역사를 선택하세요. ( sh
또는 을 사용하여 스크립트를 명시적으로 실행 하거나 bash
또는 python
와 같이 완전히 잘못된 경우에도 주석으로 무시됩니다 csh
.)
이러한 세부 사항을 수정한 후 스크립트는 다음과 같습니다.
#!/bin/bash
FTP_SERVER=ftp.ip
FTP_USER=ftp.user
FTP_PASS=ftp.passwd
FTP_DESTINATION_DIR="/destination_directory"
LOCAL_SOURCE_DIR="/home/$USER/pictures/local_pictures"
upload_file () {
local file=$1
echo "Hochladen von Datei $file"
ftp -inv "$FTP_SERVER" <<EOF
user $FTP_USER $FTP_PASS
binary
cd $FTP_DESTINATION_DIR
put $file
quit
EOF
}
export -f upload_file
find "$LOCAL_SOURCE_DIR" \( -name "*.jpg" -o -name "*.png" \) -exec bash -c 'upload_file "$0"' {} \;
더 나은 해결책은 upload_file
여러 파일 이름을 허용하고 하나의 FTP 세션만 생성하는 것입니다.
:
upload_file () {
( printf '%s\n' \
"user $FTP_USER $FTP_PASS" \
"binary" \
"cd $FTP_DESTINATION_DIR"
local file
for file; do
# print diagnostics to stderr
echo "Hochladen von Datei $file" >&2
echo "put $file"
done
echo "quit" ) |
ftp -inv "$FTP_SERVER"
}
export -f upload_file
find "$LOCAL_SOURCE_DIR" \( -name "*.jpg" -o -name "*.png" \) \
-exec bash -c 'upload_file "$@"' _ {} +
그런데, 아마도 .sh
쉘 스크립트에서 확장을 사용하지 않을 것입니다. 특히 실제로 스크립트가 아닌 경우에는 더욱 그렇습니다 sh
. 이에 대한 엄격한 규칙은 없지만 ls
확장도 없습니다. 왜 그래야 할까요?
답변2
여기서 문제는 upload_file
이 함수를 스크립트 내에서만 사용할 수 bash
있지만 find
.
이 문제를 해결하려면 다음을 수행하십시오.내보내기 기능이것을 사용하십시오 :
typeset -fx upload_file
명령을 호출하기 전에 넣으면 find
예상대로 작동합니다.
편집 : Tripleee가 의견에서 지적했습니다.export -f
도 가능. 이것은 확실히 더 읽기 쉽습니다.
답변3
함수를 올바르게 선언하지 않은 것 같습니다. 출력과 동작으로 볼 때 누락된 괄호는 function upload_file {...
다음과 같아야 합니다 function upload_file (){...
(질문을 편집한 후에는 이것이 더 이상 문제가 되지 않는다고 생각합니다). Bash에서는
단계에서 실행될 때 표시되도록 함수를 내보내야 합니다 .bash -c
find
export -f upload_file
find "$LOCAL_SOURCE_DIR"...
당신이 본대로답변.