MacOS의 rsync 스크립트에서 환경 변수의 공백 문제

MacOS의 rsync 스크립트에서 환경 변수의 공백 문제

매일 백업을 위해 실행할 Bash 스크립트가 있습니다(내 홈은 /Volumes/Norman Data/me입니다).

#!/bin/bash

# Halt the script on any errors.
set -e

# Remote server where
remote_server="example.com"

# Destination Folder on Remote Server
target_path="backup/"

# User (with sshy key) on remote server
usr="me"


# ${HOME} evaluates to '/Volumes/Norman Data/me'
# A list of absolute paths to backup. 
include_paths=(
  # "~/.ssh"
  # "~/.bash_history"
  "${HOME}/.bash_profile"
  # "~/.vimrc"
  # "~/.gitconfig"
  # "~/.gitignore"
  # "~/.zshrc"
  # "~/Artifacts"
  "${HOME}/Documents" 
  "--exclude=remote"
  # "~/Downloads"
  # "~/Desktop"
  # "~/Pictures"
  # "~/Projects --exclude 'remote'"
  # "~/Movies"
)

# A list of folder names and files to exclude.
exclude_paths=(
  ".bundle"
  "node_modules"
  "tmp"
)

# Passing list of paths to exclude
for item in "${exclude_paths[@]}"
do
  exclude_flags="${exclude_flags} --exclude=${item}"
done

# Passing list of paths to copy
for item in "${include_paths[@]}"
do
  include_args="${include_args} '${item}'"
done


str="rsync -auvzP ${exclude_flags} ${include_args} ${usr}@${remote_server}:${target_path}"
echo "Running: ${str}"
${str}

실행하면 다음과 같은 결과가 발생합니다.

building file list ... 
rsync: link_stat "/Volumes/Norman" failed: No such file or directory (2)
rsync: link_stat "/Volumes/Norman Data/me/Data/me/.bash_profile" failed: No such file or directory (2)
rsync: link_stat "/Volumes/Norman" failed: No such file or directory (2)
rsync: link_stat "/Volumes/Norman Data/me/Data/me/Documents" failed: No such file or directory (2)
0 files to consider

sent 29 bytes  received 20 bytes  32.67 bytes/sec
total size is 0  speedup is 0.00
rsync error: some files could not be transferred (code 23) at 
/BuildRoot/Library/Caches/com.apple.xbs/Sources/rsync/rsync-52/rsync/main.c(996) [sender=2.6.9]

내가 아는 한, 내 가치의 공백이 HOME문제를 일으키고 있습니다. 나는 그것을 인용하는 것이 "${HOME}/.bash_profile"공백을 관리하는 것처럼 생각했습니다. 그리고 그것은 일종의 것 같습니다. 즉, 내가 얻는 가치는 다음과 같습니다 echo "Running: ${str}".

rsync -auvzP  --exclude=.bundle --exclude=node_modules --exclude=tmp  '/Volumes/Norman Data/me/.bash_profile' '/Volumes/Norman Data/me/Documents' --exclude=remote [email protected]:backup/

그리고 이를 터미널에서 직접 실행하거나 스크립트에 붙여넣으면(대신 ${str}예상대로 작동합니다. 위의 오류는 변수를 사용할 때만 발생합니다.

내가 여기서 무엇을 놓치고 있는지 알 수 없는 것 같습니다. 누구든지 빛을 비출 수 있습니까?

** 스크립트는 다음에서 수정됨https://gitlab.com/ramawat/randomhacks/blob/master/backup_script.txt

답변1

매개변수를 저장하기 위해 배열을 사용하는 것은 옳지만, 배열을 단일 문자열로 병합하려고 하면 안 됩니다. 그러면 명령으로 실행될 때 단어로 분할되어야 하고 인용 문제가 발생하기 때문입니다.

단순히 스크립트 전체에서 배열을 사용하십시오. 예를 들어 array에 명령을 누적하십시오 cmd.

cmd=(rsync -auvzP)
for item in "${exclude_paths[@]}"
do  cmd+=("--exclude=${item}")
done
for item in "${include_paths[@]}"
do  cmd+=("${item}")
done

cmd+=("${usr}@${remote_server}:${target_path}")

set -x
"${cmd[@]}"

set -x마지막에 사용하면 쉘이 단어를 단일 인수로 보존하는 방법을 볼 수 있습니다. 사용 중인 명목상의 인용을 보여줍니다.

+ rsync ... '/Volumes/Norman Data/me/.bash_profile' ...

관련 정보