我一直在谷歌上搜索这个并搜索 Stack,但没有找到我想要做的确切事情。我真的还不能理解这个问题。
所以,假设我有 sh 脚本,它只是 gzip 的包装器(仅作为示例)。在命令行上,我想将某些内容(例如mysqldump
)的输出通过管道传输到我的脚本。然后,该脚本必须获取输入并将其通过管道传输到 gzip。
命令行示例:
mysqldump somedb | mysqldump somedb | myscript > somefile.dmp.gz
myscript 的示例(我尝试过的):
#!/usr/bin/env sh
read inp
command="echo \"$inp\" | gzip"
eval $command
这个例子可能有很多问题。请帮忙? :)
解决方案(供其他人寻找)
感谢下面的解释,我现在了解到在 SH 脚本中执行命令将简单地将输入通过管道传输到脚本,就像直接执行命令时一样。
所以在这种情况下:
猫文件|压缩包
将执行与以下完全相同的操作:
我的脚本:
#!/usr/bin/env sh
gzip
猫文件| ./myscript
所以我想指出,就我而言,还存在另一个问题:在我的现实世界脚本中,我尝试通过如下读取来检查是否存在输入流:
read inp
if [ -z "$inp" ]; then
echo "No input"
exit;
fi
事实证明,在 后read inp
,输入管道是空的。
答案1
#!/bin/sh
gzip -c
这就足够了。
$ mysqldump ... | ./script >out.gz
gzip -c
将在其标准输入上读取未压缩的数据并将压缩的数据写入其标准输出。
标准输入由管道提供,标准输出重定向到文件。管道和重定向由调用 shell 负责。
一个稍微复杂的示例,它将sed
在命令行上采用表达式并根据该表达式转换输入,或者如果未使用表达式则仅转发数据:
#!/bin/sh
if [ -n "$1" ]; then
sed -e "$1"
else
cat
fi
(在这里,使用sed -e ""
与 具有相同的效果cat
,但我想要一个更复杂的示例)
$ utility | ./script "1,5d" >out
...将从 中删除前五行输出utility
。
答案2
我不确定你的脚本的哪一部分是简单的误解,哪一部分是复杂的,因为你试图用一个更简单的例子来说明复杂的情况。
话虽如此,这将满足您的问题要求:
#!/bin/sh
gzip "$@"
答案3
要使用read
, 读取一些输入来检查它是否为空,您必须使用像zsh
这样的 shell,可以在其变量中存储任何字节值,例如:
#! /bin/zsh -
if LC_ALL=C read -ru0 -k1 byte; then
# one byte was read, the input is not empty
(printf %s "$byte"; cat) | gzip
else
echo >&2 No input
fi
或者使用某种形式的编码:
#! /bin/sh -
# get the value of the first byte as octal:
byte=$(od -An -N1 -vto1 | tr -cd 0-7)
if [ -n "$byte" ]; then
(printf "\\$byte"; cat) | gzip
else
echo >&2 No input
fi