![값에 옵션과 공백이 포함된 경로 이름이 포함된 변수를 확장합니다.](https://linux55.com/image/133489/%EA%B0%92%EC%97%90%20%EC%98%B5%EC%85%98%EA%B3%BC%20%EA%B3%B5%EB%B0%B1%EC%9D%B4%20%ED%8F%AC%ED%95%A8%EB%90%9C%20%EA%B2%BD%EB%A1%9C%20%EC%9D%B4%EB%A6%84%EC%9D%B4%20%ED%8F%AC%ED%95%A8%EB%90%9C%20%EB%B3%80%EC%88%98%EB%A5%BC%20%ED%99%95%EC%9E%A5%ED%95%A9%EB%8B%88%EB%8B%A4..png)
$ md="-l /tmp/test/my dir"
$ ls "$md"
ls: invalid option -- ' '
Try 'ls --help' for more information.
$ md="-l \"/tmp/test/my dir\""
$ ls "$md"
ls: invalid option -- ' '
Try 'ls --help' for more information.
왜 둘 다 작동하지 않는지 궁금합니다. 감사해요. 변수의 값에는 다음이 포함됩니다.
- 옵션
-l
- 공백이 포함된 경로 이름 매개변수
- 위의 두 항목은 공백으로 구분됩니다.
내 실제 질문은 다음과 같습니다. 스크립트를 작성했습니다.myscript.sh
#! /bin/bash
old_dest=""
while getopts ":l:t" opt; do
case $opt in
l)
old_dest="--link-dest \"$OPTARG\""
;;
esac
done
rsync -a --delete "$old_dest" /path/to/source /path/to/dest
-l
옵션이 포함된 명령으로 스크립트를 호출하고 싶습니다 .
myscript.sh -l "/media/t/my external hdd/backup/old one"
스크립트에서 할당된 부분은 어떻게 작성해야 하나요 old_dest
?
답변1
명령이 작동하지 않는 이유는 인용 제거/단어 분할이 재귀적으로 적용되지 않기 때문입니다.
따라서 "$old_dest"
다음 SINGLE 매개변수로 확장됩니다.
--link-dest "/media/t/my external hdd/backup/old one"
변수가 큰따옴표로 묶여 있기 때문에 이 모든 것은 매개변수입니다. (큰따옴표는 제거되지만 큰따옴표는확장의 결과, 즉 변수 값의 일부는 삭제되지 않습니다. )
반대 방향 으로 사용하면 $old_dest
여러 인수를 얻을 수 있지만 원하는 방식은 아닙니다. 다음과 같은 5개의 매개변수를 얻게 됩니다.
--link-dest
"/media/t/my
external
hdd/backup/old
one"
매뉴얼에 설명된 대로 변수 확장을 수행한 다음 토큰화를 수행하게 되기 때문입니다. 당신은 할 수 있습니다아니요변수 확장을 얻은 다음 변수의 따옴표를 해석합니다. 그리고 따옴표는 제거되지 않으므로 최종 인수는 4자가 됩니다: one"
.
다른 답변에서 말했듯이 올바른 방법은 Bash 배열을 사용하는 것입니다.
또한 Tcl이 따옴표와 단어 분리기를 처리하는 방식이 마음에 들 수도 있습니다. 쉘 토큰화에 매우 익숙하기는 하지만 더 직관적일 수도 있지만 쉘보다 Tcl에 대해 더 많이 생각해야 합니다.
답변2
당신은 bash를 사용하고 있고 bash는 배열을 지원하므로 old_dest를 배열로 만드는 것이 좋습니다.
#! /bin/bash
old_dest=()
while getopts ":l:t" opt; do
case $opt in
l)
old_dest+=('--link-dest' "$OPTARG")
;;
esac
done
printf 'Element: %s\n' rsync -a --delete "${old_dest[@]}" /path/to/source /path/to/dest
명령과 각 인수를 별도의 줄에 표시하기 위해 rsync 호출을 printf 호출로 변경했습니다. 실행 시:
./myscript.sh -l "/media/t/my external hdd/backup/old one"
결과 :
Element: rsync
Element: -a
Element: --delete
Element: --link-dest
Element: /media/t/my external hdd/backup/old one
Element: /path/to/source
Element: /path/to/dest