在 Bash 脚本中将参数传递给带有空格的命令

发布于 2024-10-13 03:04:04 字数 555 浏览 3 评论 0原文

我试图将 2 个参数传递给命令,每个参数都包含空格,我尝试转义参数中的空格,我尝试用单引号括起来,我尝试转义 \" 但没有任何效果。

这里是一个简单的例子,

#!/bin/bash -xv

ARG="/tmp/a b/1.txt"
ARG2="/tmp/a b/2.txt"

ARG_BOTH="\"$ARG\" \"$ARG2\""
cat $ARG_BOTH

当它运行时我得到以下信息:

ARG_BOTH="$ARG $ARG2"
+ ARG_BOTH='/tmp/a\ b/1.txt /tmp/a\ b/2.txt'
cat $ARG_BOTH
+ cat '/tmp/a\' b/1.txt '/tmp/a\' b/2.txt
cat: /tmp/a\: No such file or directory
cat: b/1.txt: No such file or directory
cat: /tmp/a\: No such file or directory
cat: b/2.txt: No such file or directory

I'm trying to pass 2 arguments to a command and each argument contains spaces, I've tried escaping the spaces in the args, I've tried wrapping in single quotes, I've tried escaping \" but nothing will work.

Here's a simple example.

#!/bin/bash -xv

ARG="/tmp/a b/1.txt"
ARG2="/tmp/a b/2.txt"

ARG_BOTH="\"$ARG\" \"$ARG2\""
cat $ARG_BOTH

I'm getting the following when it runs:

ARG_BOTH="$ARG $ARG2"
+ ARG_BOTH='/tmp/a\ b/1.txt /tmp/a\ b/2.txt'
cat $ARG_BOTH
+ cat '/tmp/a\' b/1.txt '/tmp/a\' b/2.txt
cat: /tmp/a\: No such file or directory
cat: b/1.txt: No such file or directory
cat: /tmp/a\: No such file or directory
cat: b/2.txt: No such file or directory

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

智商已欠费 2024-10-20 03:04:04

请参阅 http://mywiki.wooledge.org/BashFAQ/050

TLDR

将参数放入数组中并将您的程序调用为 myutil "${arr[@]}"

#!/bin/bash -xv

file1="file with spaces 1"
file2="file with spaces 2"
echo "foo" > "$file1"
echo "bar" > "$file2"
arr=("$file1" "$file2")
cat "${arr[@]}"

输出

file1="file with spaces 1"
+ file1='file with spaces 1'
file2="file with spaces 2"
+ file2='file with spaces 2'
echo "foo" > "$file1"
+ echo foo
echo "bar" > "$file2"
+ echo bar
arr=("$file1" "$file2")
+ arr=("$file1" "$file2")
cat "${arr[@]}"
+ cat 'file with spaces 1' 'file with spaces 2'
foo
bar

See http://mywiki.wooledge.org/BashFAQ/050

TLDR

Put your args in an array and call your program as myutil "${arr[@]}"

#!/bin/bash -xv

file1="file with spaces 1"
file2="file with spaces 2"
echo "foo" > "$file1"
echo "bar" > "$file2"
arr=("$file1" "$file2")
cat "${arr[@]}"

Output

file1="file with spaces 1"
+ file1='file with spaces 1'
file2="file with spaces 2"
+ file2='file with spaces 2'
echo "foo" > "$file1"
+ echo foo
echo "bar" > "$file2"
+ echo bar
arr=("$file1" "$file2")
+ arr=("$file1" "$file2")
cat "${arr[@]}"
+ cat 'file with spaces 1' 'file with spaces 2'
foo
bar
究竟谁懂我的在乎 2024-10-20 03:04:04

对于通用的“set”命令来说,这可能是一个很好的用例,它将顶级 shell 参数设置为单词列表。也就是说,$1、$2、...,$* 和 $@ 也被重置。

这为您提供了数组的一些优点,同时还保持与所有 Posix-shell 兼容。

所以:

set "arg with spaces" "another thing with spaces"
cat "$@"

This might be a good use-case for the generic "set" command, which sets the top-level shell parameters to a word list. That is, $1, $2, ... and so also $* and $@ get reset.

This gives you some of the advantages of arrays while also staying all-Posix-shell-compatible.

So:

set "arg with spaces" "another thing with spaces"
cat "$@"
三五鸿雁 2024-10-20 03:04:04

可以正常工作的示例 shell 脚本的最直接的修改是:

#! /bin/sh

ARG="/tmp/a b/1.txt"
ARG2="/tmp/a b/2.txt"

cat "$ARG" "$ARG2"

但是,如果您需要将一大堆参数包装在一个 shell 变量中,那么您就陷入困境了;没有可移植、可靠的方法来做到这一点。 (数组是 Bash 特定的;唯一可移植的选项是 seteval,这两个选项都在自找麻烦。)我认为需要这样做表明是时候用更强大的脚本语言重写了,例如 Perl 或 Python。

The most straightforward revision of your example shell script that will work correctly is:

#! /bin/sh

ARG="/tmp/a b/1.txt"
ARG2="/tmp/a b/2.txt"

cat "$ARG" "$ARG2"

However, if you need to wrap up a whole bunch of arguments in one shell variable, you're up a creek; there is no portable, reliable way to do it. (Arrays are Bash-specific; the only portable options are set and eval, both of which are asking for grief.) I would consider a need for this as an indication that it was time to rewrite in a more powerful scripting language, e.g. Perl or Python.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文