这是我的简单 bash:
cat test.sh
#!/bin/bash
echo "hello"
su - root -c /path/to/script.sh <<EOF
password
EOF
whoami
echo "good bye"
Run Code Online (Sandbox Code Playgroud)
但我收到此错误:
./test.sh
hello
su: must be run from a terminal
<current-user>
good bye
Run Code Online (Sandbox Code Playgroud)
(或者)
cat test2.sh
#!/bin/bash
echo "hello"
sudo su <<EOF
password
EOF
whoami
echo "good bye"
Run Code Online (Sandbox Code Playgroud)
又一个错误
(或者)
cat test3.sh
#!/bin/bash
echo "hello"
su root <<EOF
password
EOF
whoami
echo "good bye"
Run Code Online (Sandbox Code Playgroud)
又是错误...
当我尝试:
#!/bin/bash
echo "hello"
sudo -s <<EOF
<password>
echo Now I am root
id
echo "yes!" …Run Code Online (Sandbox Code Playgroud) 我正在尝试在 heredoc 中将其输出设置为局部变量,如下所示:
REMOTE_OUTPUT=$(ssh remote@server /bin/bash << EOF
find my/path/ -type f -not -path my/path/*/ -type f -mtime -0 | while read filename; do
if grep "ERROR" $filename; then
filenamebase=$(basename "$filename")
echo -e "\n----------------------------------------------------------\n\n$filenamebase failure:\n"
grep -n "ERROR" "$filename" | sed G
fi
done
EOF)
Run Code Online (Sandbox Code Playgroud)
但是即使 find&grep 循环正确并且确实应该返回输出,该变量仍然为空。
(否则我也有兴趣将 heredoc 的输出写入本地文件。)
我在 Bash 中执行以下代码:
bash /dev/fd/10 10<<-'SES'
cat <<EMR >> /etc/apache2/apache2.conf
#
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
EMR
SES
Run Code Online (Sandbox Code Playgroud)
但是执行中断了,我得到:
警告:第 2 行的此处文档由文件结尾分隔(需要“EMR”)
-在操作符和包含 heredoc 的名称之间添加以允许列表。注意:如果您复制上面的代码在您的计算机中进行测试,您需要将所有前导空格更改为制表符(制表符),因为StackExchange将原始制表符更改为空格。
造成这种情况的可能原因有多种,以下是我排除的一些原因:
我用 Notepad++ 编辑文件并打开“显示所有符号”模式以确保所有缩进都是基于表格的(见红色箭头)并且所有行尾字符(EOL)都是LF基于 unix 的(没有任何CR字符) ):
而且,编码是UTF-8,所以这不是编码问题。
<<-):这似乎为加连字符(<<-)不会做剥离所有领先的标签,因为当我手动删除所有领先的标签其工作任何(或所有领先的标签每个定界符之前)的定界符不按预期方式工作。人们可以认为连字符并不是真正的破折号,但为什么不是呢?我没有办法验证这一点。
其他不使用 Windows 和使用不同的包含 …
我很好奇 heredocs 如何作为文件传递给命令行实用程序背后的理论。
最近,我发现我可以将文件作为 heredoc 传递。
例如:
awk '{ split($0, arr, " "); print arr[2] }' <<EOF
foo bar baz
EOF
bar
Run Code Online (Sandbox Code Playgroud)
出于以下几个原因,这对我来说是有利的:
例如:
ruby <<EOF
puts "'hello $HOME'"
EOF
'hello /Users/mbigras'
ruby <<'EOF'
puts "'hello $HOME'"
EOF
'hello $HOME'
Run Code Online (Sandbox Code Playgroud)
我不清楚发生了什么。似乎shell认为heredoc是一个内容等于heredoc值的文件。我已经将这种技术与 cat 一起使用,但我仍然不确定发生了什么:
cat <<EOL
hello world
EOL
hello world
Run Code Online (Sandbox Code Playgroud)
我知道cat打印文件的内容,所以大概这个 heredoc 是某种临时文件。
当我“将heredoc传递给命令行程序”时,我对究竟发生了什么感到困惑。
这是使用ansible-playbook的示例。我将实用程序作为 heredoc 传递给剧本;但是它失败了,如使用所示echo $?:
ansible-playbook -i localhost, -c local <<EOF &>/dev/null
---
- hosts: all …Run Code Online (Sandbox Code Playgroud) 我创建了一个函数
function getqueue() {
urlqueuename="urlcall"
ouput=`curl $urlqueuename`
queue=$(echo $ouput | jq -r '.queueName')
echo $queue
}
Run Code Online (Sandbox Code Playgroud)
我正在使用脚本中的 ssh 调用,例如:
ssh -T -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i "$HOME_DIR/<pemfile>" $username@$IP<<EOF
queue=$(getqueue)
echo "Queue name : $queue"
EOF
Run Code Online (Sandbox Code Playgroud)
但是队列为空,也尝试$(typeset -f)在远程调用中使用函数,但变量仍然为空
任何有关相同的指导将不胜感激。
假设我想在某处有一个多行字符串的模板:
I have some
text with ${placeholders}
in this and some ${different}
ones ${here} and ${there}
Run Code Online (Sandbox Code Playgroud)
用用户输入替换占位符的最佳方法是什么?here-documents 会很好用吗?
这有效:
#!/bin/bash
foo() {
gen() {
cat <<EOF
bar
EOF
true
}
gen
}
foo
export -f foo
bash -c foo
Run Code Online (Sandbox Code Playgroud)
这在最后一行失败:
#!/bin/bash
foo() {
gen() {
cat <<EOF
bar
EOF
}
gen
}
foo
export -f foo
bash -c foo
Run Code Online (Sandbox Code Playgroud)
给予:
bar
bash: foo: line 9: syntax error: unexpected end of file
bash: error importing function definition for `foo'
bash: foo: command not found
Run Code Online (Sandbox Code Playgroud)
为什么true需要最后一个?
$ bash --version
GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2019 Free …Run Code Online (Sandbox Code Playgroud) 我想将配置信息写入一个包含美元符号 ( $)的特定文件。这似乎是一个问题。
这是我所做的:
$ cat >> /etc/nginx/nginx.conf <<EOF
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log;
#error_log /var/log/nginx/error.log notice;
#error_log /var/log/nginx/error.log info;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
## Detect when HTTPS is used
map $scheme $https {
default off;
https on;
}
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" …Run Code Online (Sandbox Code Playgroud) 我只询问与文件中的传统输入重定向具有类似效果的用法。
<<<"$(<file)"
Run Code Online (Sandbox Code Playgroud)
据我所知相当于
<file
Run Code Online (Sandbox Code Playgroud)
在我看来,这些在功能上是等效的。在低级别看来,<<< here 文档实际上可能会导致更多的数据副本一次在内存中。
我知道 bash 和 zsh 中都存在这种类型的重定向,但我不熟悉它的实现方式,尽管我看到 zsh 联机帮助页包含一些实现细节。
我希望cat在一行中运行一个heredocument,而不是 3 行的自然语法(开场白、内容和分隔符)。我这样做的需要主要是美观,因为重定向的内容旨在成为手册文本文件的一部分,我想在该特定文件中尽可能多地保存行)。
做cat <<< TEST > ~/myRep/tiesto tiesto TEST(我通常会分成 3 部分)会导致错误:
tiesto: 没有这样的文件或目录
测试:没有这样的文件或目录。
甚至可以在 Bash 中执行一行 heredocuments 吗?
here-document ×10
bash ×6
shell ×3
quoting ×2
ansible ×1
cat ×1
command-line ×1
here-string ×1
shell-script ×1
ssh ×1
string ×1
su ×1
sudo ×1
zsh ×1