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

时间:2019-07-15 09:43:56

标签: bash git-bash

我想自动执行Git的许多版本控制步骤。在我在Bash脚本中使用git commit -S -m ${var}之前,我一直是成功的。这行代码给我(路径规格错误x词数)-1 ...除非我使用eval。 eval如何使我的脚本起作用?

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

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如何做到这一点?

我在Windows 8.1 PC上使用GNU bash,版本4.4.19(1)-发行版(x86_64-pc-msys)和git版本2.16.2.windows.1。

1 个答案:

答案 0 :(得分: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]
  • 但是它并不能阻止,因为单引号不会重新解释,但就像可变内容中的任何其他字符一样

跟随示例

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

带有eval的单引号将被重新解释,但其他所有在bash中具有特殊含义的字符也将被重新解释(;&${ .. }, ..)

例如,假设以下提交消息可以注入任意命令。

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