在 shell 脚本中...
如何在不剥离任何尾随换行符的情况下将 stdin 捕获到变量?
现在我已经尝试过:
var=`cat`
var=`tee`
var=$(tee)
Run Code Online (Sandbox Code Playgroud)
在所有情况下$var都不会有输入流的尾随换行符。谢谢。
另外:如果输入中没有尾随换行符,则解决方案不得添加.
根据接受的答案更新:
我在代码中使用的最终解决方案如下:
function filter() {
#do lots of sed operations
#see https://github.com/gistya/expandr for full code
}
GIT_INPUT=`cat; echo x`
FILTERED_OUTPUT=$(printf '%s' "$GIT_INPUT" | filter)
FILTERED_OUTPUT=${FILTERED_OUTPUT%x}
printf '%s' "$FILTERED_OUTPUT"
Run Code Online (Sandbox Code Playgroud)
如果您想查看完整代码,请查看expandr的 github 页面,这是我为信息安全目的开发的一个小的开源git 关键字扩展过滤器shell 脚本。根据.gitattributes文件(可以是特定于分支的)和git config 中设置的规则,无论何时检入或检出存储库,git 都会通过expandr.sh shell 脚本通过管道传输每个文件。(这就是为什么保留任何尾随换行符或缺少换行符至关重要。)这使您可以清理敏感信息,并为测试、暂存和实时分支交换不同的环境特定值集。
考虑以下 shell 脚本
val=($ls)
Run Code Online (Sandbox Code Playgroud)
ls 不提供任何 shell 文本输出。现在,我们如何在执行命令时在屏幕上获取输出文本?
我可以打印 val 的值来获取输出,但使用 echo 不是重点。因此,使用以下行并非如此
echo $val
Run Code Online (Sandbox Code Playgroud)
那么,简而言之,我如何获得在 shell 中同时执行的当前命令的输出,就像您自己执行命令一样?
$ touch file{1..12}
$ echo *e{1..12}
file1 file2 file3 file4 file5 file6 file7 file8 file9 file10 file11 file12
$ echo *{1..12}
file1 file11 file12 file2 file3 file4 file5 file6 file7 file8 file9 file10 file11 file12
Run Code Online (Sandbox Code Playgroud)
我不明白为什么会这样。请问有人可以解释一下吗?
我试图使用执行新行echo并尝试执行以下两个命令:
第一条命令:
echo $'Hello World\nThis is a new line'
Run Code Online (Sandbox Code Playgroud)
回复:
Hello World
This is a new line
Run Code Online (Sandbox Code Playgroud)第二个命令:
echo $"Hello World\nThis is a new line"
Run Code Online (Sandbox Code Playgroud)
回复:
Hello World\nThis is a new line
Run Code Online (Sandbox Code Playgroud)我的问题是$' '用$" "in包裹的字符串与用bash's包裹的字符串有什么区别echo?
我试图回显用 base64 编码的密钥和证书文件的内容,以便我可以将输出复制到其他地方。
我找到了这个线程:将文件的内容重定向到命令回显?它显示了如何回显文件内容,并找到了保留换行符以进行编码的方法。但是,当我添加| base64这会将输出分成多行时,尝试添加第二echo行只会用空格替换换行符。
$ echo "$(cat test.key)" | base64
LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRZ0lCQURBTkJna3Foa2lHOXcwQkFRRUZB
QVNDQ1N3d2dna29BZ0VBQW9JQ0FRRFF4Tkh0aHZvcEp1Z0EKOHBsSUNUUU1pOGMwMzRERlR6Z1E5
ME5tcE5zN2hRczNQZ0QwU2JuSFcyVGxqTS9oM1F1QVE0Q1dqaHRiV1ZUbgpSREcveGxWRFBESVVV
MzB1UHJnK0N6dlhOUkhzQkE9PQotLS0tLUVORCBQUklWQVRFIEtFWS0tLS0tCg==
$ echo $(echo "$(cat test.key)" | base64)
LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRZ0lCQURBTkJna3Foa2lHOXcwQkFRRUZB QVNDQ1N3d2dna29BZ0VBQW9JQ0FRRFF4Tkh0aHZvcEp1Z0EKOHBsSUNUUU1pOGMwMzRERlR6Z1E5 ME5tcE5zN2hRczNQZ0QwU2JuSFcyVGxqTS9oM1F1QVE0Q1dqaHRiV1ZUbgpSREcveGxWRFBESVVV MzB1UHJnK0N6dlhOUkhzQkE9PQotLS0tLUVORCBQUklWQVRFIEtFWS0tLS0tCg==
Run Code Online (Sandbox Code Playgroud)
所需的输出是:
LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRZ0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQ1N3d2dna29BZ0VBQW9JQ0FRRFF4Tkh0aHZvcEp1Z0EKOHBsSUNUUU1pOGMwMzRERlR6Z1E5ME5tcE5zN2hRczNQZ0QwU2JuSFcyVGxqTS9oM1F1QVE0Q1dqaHRiV1ZUbgpSREcveGxWRFBESVVVMzB1UHJnK0N6dlhOUkhzQkE9PQotLS0tLUVORCBQUklWQVRFIEtFWS0tLS0tCg==
Run Code Online (Sandbox Code Playgroud)
我怎样才能实现这个输出?
$ echo > 1 2 3; ls -latr 1; cat 1
-rw-rw-r-- 1 kahn kahn 4 Jun 23 14:05 1
2 3
Run Code Online (Sandbox Code Playgroud)
这与>重定向的评估有关吗?这样:
echo > 1 2 3
Run Code Online (Sandbox Code Playgroud)
也可以重写为 并且在技术上是:
echo 2 3 > 1
Run Code Online (Sandbox Code Playgroud)
?
是否有任何资源可以更好地理解 IO 重定向的操作顺序及其评估方式?我承认这个例子可能没什么用,甚至不会经常出现,但我想更好地了解这里到底发生了什么。
我喜欢set -x在脚本中使用来显示正在发生的情况,特别是如果脚本将在 CI/CD 管道中运行并且我可能需要事后调试一些故障。
这样做的一个烦恼是,如果我想向用户回显一些文本(例如,状态消息或"I'm starting to do $X"),那么该消息会输出两次 - 一次用于echo回显命令本身,然后一次作为该echo命令的输出。
有什么好方法可以让这个变得更好?一种解决方案是这样的:
set -x
... bunch of normal commands that get echoed
(
# Temporarily don't echo, so we don't double-echo
set +x
echo "Here is my status message"
)
... rest of commands get echoed again
Run Code Online (Sandbox Code Playgroud)
但这样做的两个问题是
set +x也呼应了,这是不可取的。还有其他效果好的选择吗?
我正在尝试做类似的事情
alias ftp='echo do not use ftp. Use sftp instead.'
Run Code Online (Sandbox Code Playgroud)
只是为了ftp不会被意外使用。但我注意到
ftp abcd.com
Run Code Online (Sandbox Code Playgroud)
将导致命令回显
do not use ftp. Use sftp instead. abcd.com
Run Code Online (Sandbox Code Playgroud)
因为abcd.com被认为是 的参数echo。
有没有办法让 Bash 不添加abcd.com到替换中,或者echo不将其作为额外的参数?(每种方法都有解决方案吗?)
我以为我能做到
alias ftp='sftp'
Run Code Online (Sandbox Code Playgroud)
但我只想让命令全部停止以提醒自己不要使用ftp.
我想在 shell 脚本中打印一个复选标记和一个十字标记:
#!/bin/bash
echo -e "\xE2\x9C\x94 existing"
echo -e "\xE2\x9D\x8C missing"
Run Code Online (Sandbox Code Playgroud)
为什么这不起作用?
我正在编写一个 shell 脚本,我需要打印脚本的第 n 个参数。
例如,假设我们有n=3并且我们的脚本使用足够的参数运行。现在我需要打印第nth 个参数,即$3。
但如果n=2,我们会打印参数$2。
我不想使用if语句。我想做类似的事情
echo $($n)
Run Code Online (Sandbox Code Playgroud)
但上面的方法并没有按照我需要的方式工作。