eval 如何停止此脚本中的 pathspec 错误?

How does eval stop the pathspec errors in this script?

我想自动化 Git 的许多版本控制步骤。在 Bash 脚本中使用 git commit -S -m ${var} 之前,我一直很成功。这一行给我(pathspec errors x # of word)- 1 ...除非我使用eval。 eval 如何使我的脚本工作?

我以为 有答案,但我的问题涉及字符串,而不是数组。

Gif video of the broken vs. working Bash script

代码损坏

brokenCommitCode () {
  # Give it a multi-word, space-separated message
  read -p 'Commit message (use quotes): ' commitMsg
  commitMsg="'${commitMsg}'"
  echo ${commitMsg}
  git add -A &&
  git commit -S -m ${commitMsg} 
}

工作代码

workingCommitCode () {
  read -p 'Commit message (use quotes): ' commitMsg
  commitMsg="'${commitMsg}'"
  echo ${commitMsg}
  git add -A &&
  eval git commit -S -m ${commitMsg} 
}

我希望 brokenCommitCode 能够正确提交我在提示中输入的消息。实际结果是到达git commit -S -m ${commitMsg}时出现pathspec错误。 eval 如何进行这项工作?

我正在使用 GNU bash,版本 4.4.19(1)-release (x86_64-pc-msys) 和 git 版本 2.16.2.windows.1 Windows 8.1 电脑。

正确的解决方法是

funname() {
    read -p 'Commit message (use quotes): ' commitMsg
    echo "${commitMsg}"
    git add -A &&
    git commit -S -m "${commitMsg}"
}

为什么 eval 似乎可以解决:

  • 添加到 commitMsg 变量的单引号(似乎是为了防止消息参数被空格分割)

查看以下消息会发生什么情况:

commitMsg="this is a message"

git commit -S -m ${commitMsg} 
git commit -S -m this is a message
[error because "is" "a" "message" are taken as different additional arguments]
  • 但是它并没有阻止,因为单引号不是 re-interpreted 但就像变量内容中的任何其他字符一样

接着举例

git commit -S -m ${commitMsg} 
git commit -S -m \'this is a message\' 
[error "is" "a" "message'" are taken as different additional arguments]

在 eval 中,单引号是 re-interpreted,但也是在 bash 中具有特定含义的任何其他字符(;&${ ..},..)

假设下面的提交消息可以注入任意命令。

commitMsg="message'; ls -l; echo 'done"
git commit -S -m 'message'; ls -l; echo 'done'