bash 如何将带有多个引号/特殊字符的行回显到文件中?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11994796/
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-18 03:03:41  来源:igfitidea点击:

How to echo line with multiple quotes/special characters into file?

linuxbashshellecho

提问by user1604139

I am trying to echo the following line into a .profile but it keeps getting confused by either the many quotes or special characters.

我试图将以下行回显到 .profile 中,但它一直被许多引号或特殊字符弄糊涂。

bind '"e[A": history-search-backward'

bind '"e[A": history-search-backward'

I've tried all sorts of things but can't get it nailed.

我已经尝试了各种各样的事情,但无法解决问题。

This is what I currently have:

这是我目前拥有的:

sudo su -c 'echo "bind \'\"\\e[A\": history-search-backward\'" >> /etc/profile' -

sudo su -c 'echo "bind \'\"\\e[A\": history-search-backward\'" >> /etc/profile' -

This is what it returns:

这是它返回的内容:

su: user '"\e[A": does not exist

su: user '"\e[A": does not exist

Yet if I just use:

然而,如果我只是使用:

echo bind \'\"\\e[A\": history-search-backward\'" >> /home/user/testfile

echo bind \'\"\\e[A\": history-search-backward\'" >> /home/user/testfile

It works just fine.

它工作得很好。

I have all manner of "sudo su -c "echo blah..." in the rest of my script that work just fine.

在我的脚本的其余部分,我有各种各样的“sudo su -c”echo blah ...”,它们工作得很好。

Any ideas?

有任何想法吗?

回答by chepner

Try this

尝试这个

sudo su -c $'echo \"bind \'\"\e[A\": history-search-backward\'\" >> /etc/profile\' -'

From the bash man page:

从 bash 手册页:

A single quote may not occur between single quotes, even when preceded by a backslash.

单引号之间不能出现单引号,即使前面有反斜杠。

Text quoted by $'...'may contain backslash-escaped quotes, both single and double.

引用的文本$'...'可能包含反斜杠转义的引号,包括单引号和双引号。

Another option is to add a simpler expression to ~/.inputrc:

另一种选择是向 中添加一个更简单的表达式~/.inputrc

echo '"\e[A": history-search-backward' >> ~/.inputrc

There doesn't seem to be a system-wide equivalent of .inputrcthat is read by all users. Also, this makes the key binding available to any program that uses readline. If you really do want to restrict it to bash, add a conditional expression:

似乎没有一个系统范围的等效项可供.inputrc所有用户阅读。此外,这使得任何使用 readline 的程序都可以使用键绑定。如果您确实想将其限制为 bash,请添加条件表达式:

cat >> ~/.inputrc <<'EOF'
$if Bash
"\e[A": history-search-backward
$endif
EOF

回答by Gilles 'SO- stop being evil'

Every character is interpreted literally between single quotes, except 'itself. So you can put a single quote inside a literal string like this: 'single'\''quoted'is the string single'quoted.

每个字符都在单引号之间按字面解释,除了'它自己。因此,您可以在文字字符串中放置一个单引号,如下所示:'single'\''quoted'is the string single'quoted

Your command is complicated because there are two shells involved: the shell you're running this command from, and the shell that suruns. Note that it's weird to run sudo susince sudoalready runs the specified command as root; sudo sh -c …makes more sense. So you need to quote for both. It's usually clearest to use single quotes for the outer shell, and double quotes or single quotes or backslashes for the inner shell.

您的命令很复杂,因为涉及到两个 shell:运行此命令的 shell 和su运行的 shell 。请注意,运行很奇怪,sudo su因为sudo已经以 root 身份运行了指定的命令;sudo sh -c …更有意义。所以你需要为两者报价。通常最清楚的是对外壳使用单引号,对内壳使用双引号或单引号或反斜杠。

There's another problem with your command: you're targeting the wrong file. /etc/profileis only read by login shells, whereas the bindcommand is specific to bash but should be read by all instances of bash, not just login shells. Instead of writing this line to /etc/profile, you should write it to the system-wide bashrc, if there is one (it's usually /etc/bash.bashrc).

您的命令还有另一个问题:您定位的是错误的文件。/etc/profile仅由登录 shell 读取,而该bind命令特定于 bash,但应由 bash 的所有实例读取,而不仅仅是登录 shell。如果有的话(通常是)/etc/profile,而不是将这一行写入 ,您应该将其写入系统范围bashrc/etc/bash.bashrc

sudo sh -c 'echo "bind '\''\"\e[A\": history-search-backward'\''" >>/etc/bash.bashrc'

You may put this setting directly into the readline configuration file, /etc/inputrc. You'll save on a level of quoting.

您可以将此设置直接放入 readline 配置文件中/etc/inputrc。您将节省一定程度的引用。

sudo sh -c 'echo '\''"\e[A": history-search-backward'\'' >>/etc/inputrc'

An easier way to pass an arbitrary string to a command would be to pass it as input instead of as an argument and use a here document.

将任意字符串传递给命令的一种更简单的方法是将其作为输入而不是作为参数传递并使用here 文档

sudo sh -c 'cat >>/etc/inputrc' <<'EOF'
"\e[A": history-search-backward
EOF