使用空格将参数传递给 Bash 脚本中的命令

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4753993/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 23:19:00  来源:igfitidea点击:

Passing arguments to a command in Bash script with spaces

bashshellunixscriptingescaping

提问by Dougnukem

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.

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

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

回答by SiegeX

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

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

TLDR

TLDR

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

将您的 args 放在一个数组中并将您的程序称为 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

回答by DigitalRoss

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.

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

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

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

So:

所以:

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

回答by zwol

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

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

#! /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 setand 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.

但是,如果您需要将一大堆参数包含在一个 shell 变量中,那您就麻烦了;没有便携、可靠的方法来做到这一点。(数组是 Bash 特定的;唯一的可移植选项是setand eval,这两个选项都令人痛苦。)我认为需要这样做来表明是时候用更强大的脚本语言重写,例如 Perl 或 Python .