使用Bash将以空格分隔的文件列表发送到Git [英] Using Bash to send space separated list of files to Git

查看:149
本文介绍了使用Bash将以空格分隔的文件列表发送到Git的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个让我感到迷惑.

我正在创建一个Bash脚本,该脚本将文件复制到一系列存储库中,然后添加它们以进行提交.这些文件有时在文件名中带有空格,因此需要用引号引起来.

I'm creating a Bash script which copies files into a series of repos and then adds them for commit. The files sometimes have spaces in the filenames, so they need to be quoted.

我在Bash:$x的变量中创建了一个用引号引起来的用空格分隔的文件名列表.当我运行echo $x时,我得到了:

I've created a quoted space-separated list of filenames in a variable in Bash: $x. When I run echo $x I get this:

'test 01.sql' 'test 02.sql' 'test_03.sql'

如果我手动运行以下命令(在适当的目录中),则没有问题:

If I manually run the following (in the appropriate directory), I have no problem:

git add 'test 01.sql' 'test 02.sql' 'test_03.sql'

但是在我的脚本中,如果我运行:

But in my script, if I run:

git add $xgit add "$x"git add "${x}",我从Git收到致命的pathspec错误.

git add $x or git add "$x" or git add "${x}", I get a fatal pathspec error from Git.

致命的:pathspec``test 01.sql''test 02.sql''test_03.sql''与任何文件都不匹配

fatal: pathspec ''test 01.sql' 'test 02.sql' 'test_03.sql'' did not match any files

我已经尝试了单引号和双引号的字符串,没有区别.

I've tried both single and double quoted strings with no difference.

该示例已简化.完整版使用文件的绝对路径.

The example has been simplified. The full version uses absolute paths to the files.

'/Volumes/HardDrive/Repo/queries/test 01.sql' '/Volumes/HardDrive/Repo/queries/test 02.sql' '/Volumes/HardDrive/Repo/queries/test_03.sql'

它在从脚本中回显并手动粘贴到git add命令中时有效,但是在从脚本中的变量传递时不起作用.

It works when echoed from the script and pasted manually into the git add command, but doesn't work when passed from a variable in the script.

推荐答案

用shell引号引起的名称列表在用于程序化(而非人工)输入的格式选择方面非常差.

这似乎是不直观的,但这是有原因的:当您在shell中键入命令时,该命令将被解析为代码;它能够包含重定向,命令替换以及其他具有潜在危险副作用的扩展.

This seems nonintuitive, but it's true for a reason: When you type in a command in the shell, that command is parsed as code; it's able to contain redirections, command substitutions, and other expansions with potentially dangerous side effects.

为了使数据可以安全地处理而没有代码评估的风险,外壳程序仅在大多数其他解析阶段(不包括扩展结果的字符串拆分和globbing)完成之后,才执行参数扩展.

To allow data to be safely handled without any risk of evaluation as code, the shell performs parameter expansion only after most other parsing stages (exclusive of string splitting of expansion results and globbing) are complete.

如果您手动生成此输入并检查其正确性,则可以使用eval:

If you were manually generating this input and reviewing it for correctness, you could use eval:

# THIS IS DANGEROUS unless you trust your string to contain no malicious content!
files="'test 01.sql' 'test 02.sql' 'test_03.sql'"
eval "git add -- $files"


但是,如果您以编程方式生成此列表,请将其格式化为NUL分隔的流,然后使用xargs:

# generate a list in unambiguous NUL-delimited form
printf '%s\0' "/path/to/file 1" "/path/to/file 2" >file.txt

# use that list to run `git add` for the named files
xargs -0 git add -- <file.txt

...或者可以将NUL分隔的流读入shell数组:

...or a NUL-delimited stream can be read into a shell array:

# read that list into an array
files=( )
while IFS= read -r -d '' filename; do files+=( "$filename" ); done <files.txt

# ...and use the array
git add -- "${files[@]}"

这篇关于使用Bash将以空格分隔的文件列表发送到Git的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆