bash 输入输出和重定向 ¶
#BASH #Shell 输入与输出重定向常见用法
一、将命令输出保存到文件 ¶
# 覆盖和追加
command > overwrited.txt
command >> appended.txt
# 重定向标准输出和错误
command &> logs.txt
command > logs.txt 2>&1
二、将命令的输出结果传递给另外一个命令:管道 ¶
ps -ef | grep docker
三、将命令的输出作为一个临时文件,提供给另一个命令 ¶
#!/bin/bash
WorkDir=$(cd $(dirname $0); pwd)
EXPORT_TO=$WorkDir/markdown
[ -d $EXPORT_TO ] || mkdir $EXPORT_TO
readarray -t memos_id < <(sqlite3 $WorkDir/storage/memos_dev.db 'select id from memo;')
# 等价于
# sqlite3 $WorkDir/storage/memos_dev.db 'select id from memo > /tmp/memo_id.txt
# readarray -t /tmp/memo_id.txt
# rm /tmp/memo_id.txt
for mem in "${memos_id[@]}"; do
echo "EXPORT memo id ${mem}"
sqlite3 $WorkDir/storage/memos_dev.db "select content from memo where id=$mem;" > "$EXPORT_TO/$mem.md"
done;
这段脚本有两个关键点:
- 单 '<' 输入重定向,将一个“文件”内容作为标准输入提供给前面的程序
- '<(command)' 将一个命令的输出作为一个文件名提供给前面的命令
- 因此上面的那个命令的意思就是,将后面一条命令输出结果作为标准输入,提供给 readarray 命令,也就是生成一个数组。
- '$(command)' 和 '<(command)' 的区别,'$(command)' 表示抓取 command 输出的内容,具体是什么作用,实际上要看它展开的位置,比如 'command_1 < $(command2)' 这条命令表示将 command 的输出作为一个文件名,然后将该文件内容提供给 command_1 做为输入
四、HereDoc 提供一整段预先编制好的内容作为前面命令的标准输入 ¶
readarray -t fruits << End
apple
banana
orange
End
当检测到结束符时,系统将之前的内容作为标准输入提供给 readarray
总结 ¶
将连接符左右两边的命令分为左值和右值,重定向符号的选择如下
| 左值 | 右值 | 定向符号 | 备注 |
|---|---|---|---|
| 命令 | 文件 | >,>>,&> | 命令输出重定向到文件 |
| 命令 | 命令 | | | 将命令输出提供给右侧命令 |
| 命令 | 命令 | < <(command) | 将右侧命令输出作为文件,注意空格 |
| 命令 | 文本 | << EndTag | 将右侧大段文本,以EndTag结束,作为文件,提供给前面命令 |
| 命令 | 文件 | < | 将右侧文件内容定向给左侧命令标准输入 |
实际上 <(command) 是可以单用的,它可以用在需要以文件名作为命令行参数的场合。比如,在较老版本的openssl签署SAN证书时,会使用到以下命令
openssl req -nodes -x509 -sha256 -newkey rsa:4096 \
-keyout example.org.key \
-out example.org.crt \
-days 356 \
-subj "/C=NL/ST=Zuid Holland/L=Rotterdam/O=ACME Corp/OU=IT Dept/CN=example.org" \
-extensions san \
-config <( \
echo '[req]'; \
echo 'distinguished_name=req'; \
echo '[san]'; \
echo 'subjectAltName=DNS:localhost,DNS:example.org')
其中的 -config 参数,原本就需要提供一个文件名。
评论
请登录后发表评论。
暂无评论。成为第一个评论者!