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
How to echo line with multiple quotes/special characters into file?
提问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

