2020-03-19 21:50:53
cat 命令及here doc 创建文件(自己总结)补充与sudo 连用
引言:
今天发现用sudo + cat + here document 竟然无法在拥有root 权限的情况下创建文件,例如:
sudo cat <<< hello > /opt/h.txt
-bash: /opt/h.txt: Permission denied
分析:
man cat # 才知道之前写错了cat 原来是concatenate 的缩写,但仍然是连接的意思,这点没错
cat - concatenate files and print on the standard output
cat 的作用就是连接文件打印其内容到标准输出即屏幕上
回到之前的命令 sudo cat <<< 'hello' > /opt/h.txt 可以分解成两步
sudo cat <<< 'hello' # 第一步,得到'hello' 打印到标准输出
echo 'hello' > /opt/h.txt # 第二步,这里用echo 模拟cat 的结果,
之所以这样划分是因为,重定向> 并不是任何命令的一部分,它是将上一个命令的结果输出到文件中
甚至可以将重定向> 看成另一个命令,例如:> /tmp/t.txt 即可创建一个空文件,类似于touch
这里,sudo 只让紧随其后的cat 有了root 的权限,但重定向> 还是原用户的权限
一般用户是没有/opt 的写入权限的,自然报了“权限拒绝”的错误
解决:
方法一,将命令包含在一个bash 命令中
sudo bash -c "cat <<< 'hello' > /opt/h.txt"
方法二,使用tee 代替>,tee -a 代替>>,强烈推荐!!!
sudo tee /opt/h.txt <<< hello > /dev/null
# tee - read from standard input and write to standard output and files
# tee 会将标准输入同时输出到文件和标准输出
# 以上命令用here string 作为标准输入,将标准输出重定向到/dev/null 让其没有任何显示
参考:
Linux 管道指令pipe 与shell 重定向的区别
https://my.oschina.net/badboy2/blog/478952
管道命令与重定向区别
1. 左边的命令应该有标准输出 | 右边的命令应该接受标准输入
2. 左边的命令应该有标准输出 > 右边只能是文件
3. 左边的命令应该需要标准输入 < 右边只能是文件
2020-03-19 18:20:48
补充:
<< 是Here document
<<< 则是Here String,只有一行的Here document
2020-02-21 10:11:54
cat 命令及here doc 创建文件(自己总结)
cat 缩写于catenate 连接的意思。
cat 命令有一个输入口和一个输出口,默认什么都不输的话它会将标准输入(键盘)和标准输出(键盘)连接在一起。
# 操作样例
cat # 敲下回车,你输入什么屏幕上就打印什么。
cat file1 # 将file1 作为输入,标准输出为输出
cat file1 > file2 # 将file1 作为输入,file2 作为输出,即将file1 的内容输出到file2 去
# 注意:输入输出并没有先后顺序,cat 只认大于号 > 为输出的标志,所以以上命令等同于
cat > file2 file1 # 这里输出还是file2,输入仍是file1,效果跟上一条命令一样
# 所以,我们用cat 配合here doc 创建文件的时候,会看到两种都正确的写法
cat > file1 << EOF # > 输出指向file1,输入是here doc
aaa
bbb
EOF
# 等同于
cat << EOF > file1 # 输出仍是file1,输入仍是here doc
aaa
bbb
EOF
# 注意 << 是here doc 的一部分即文档开始,把整个here doc 想象成一个虚拟的文件,本质上
cat << EOF
aaa
bbb
EOF
等同于
cat file.txt # 假设file.txt 的内容也是aaa 换行bbb
关于here document 其他用法参考: