我正在尝试将管道的输出转换为变量。我尝试了以下几件事:
echo foo | myvar=$(</dev/stdin)
echo foo | myvar=$(cat)
echo foo | myvar=$(tee)
Run Code Online (Sandbox Code Playgroud)
但是$myvar
是空的。
我不想做:
myvar=$(echo foo)
Run Code Online (Sandbox Code Playgroud)
因为我不想生成子shell。
有任何想法吗?
编辑:我不想生成子shell,因为管道之前的命令需要编辑全局变量,而这在子shell中是做不到的。它可以?的echo
东西只是为了简化。它更像是:
complex_function | myvar=$(</dev/stdin)
Run Code Online (Sandbox Code Playgroud)
我不明白,为什么这不起作用。这例如:
complex_function | echo $(</dev/stdin)
Run Code Online (Sandbox Code Playgroud) 为简单起见,我想做:
echo cart | assign spo;
echo $spo
Run Code Online (Sandbox Code Playgroud)
输出:购物车
是否assign
存在这样的应用程序?
我知道使用替换来做到这一点的所有方法。
如果我调用某个命令,例如,echo
我可以在其他几个命令中使用该命令的结果tee
。例子:
echo "Hello world!" | tee >(command1) >(command2) >(command3)
Run Code Online (Sandbox Code Playgroud)
使用 cat 我可以收集几个命令的结果。例子:
cat <(command1) <(command2) <(command3)
Run Code Online (Sandbox Code Playgroud)
我希望能够同时做这两件事,这样我就可以tee
在其他东西的输出上调用这些命令(例如echo
我写的),然后在一个输出上收集所有结果cat
.
保持结果为了这一点很重要,这意味着输出的线路command1
,command2
并且command3
不应该纠缠在一起,但订购的命令是(因为它与发生cat
)。
可能有比cat
和更好的选择,tee
但这些是我目前所知道的。
我想避免使用临时文件,因为输入和输出的大小可能很大。
我怎么能这样做?
PD:另一个问题是这种情况发生在循环中,这使得处理临时文件变得更加困难。这是我拥有的当前代码,它适用于小型测试用例,但是在以某种我不理解的方式从 auxfile 读取和写入时,它会创建无限循环。
somefunction()
{
if [ $1 -eq 1 ]
then
echo "Hello world!"
else
somefunction $(( $1 - 1 )) > auxfile
cat <(command1 < auxfile) \
<(command2 < auxfile) \
<(command3 < auxfile)
fi …
Run Code Online (Sandbox Code Playgroud) 由于种种原因,我雄心勃勃地尝试将 c++ 代码转换为 bash。
此代码读取和操作特定于我的子字段的文件类型,该文件类型完全以二进制形式编写和构建。我的第一个与二进制相关的任务是完全按原样复制头的前 988 个字节,并将它们放入一个输出文件中,我可以在生成其余信息时继续写入该文件。
我很确定我当前的解决方案不起作用,实际上我还没有找到确定这一点的好方法。因此,即使它实际上编写正确,我也需要知道如何测试以确保!
这就是我现在正在做的:
hdr_988=`head -c 988 ${inputFile}`
echo -n "${hdr_988}" > ${output_hdr}
headInput=`head -c 988 ${inputTrack} | hexdump`
headOutput=`head -c 988 ${output_hdr} | hexdump`
if [ "${headInput}" != "${headOutput}" ]; then echo "output header was not written properly. exiting. please troubleshoot."; exit 1; fi
Run Code Online (Sandbox Code Playgroud)
如果我使用 hexdump/xxd 来检查文件的这一部分,虽然我不能完全阅读其中的大部分内容,但似乎有些不对劲。我为比较而编写的代码只告诉我两个字符串是否相同,而不是按照我希望的方式复制它们。
有没有更好的方法在 bash 中做到这一点?我可以简单地复制/读取本机二进制中的二进制字节,逐字复制到文件吗?(理想情况下也存储为变量)。
回答这个问题让我提出了另一个问题:
我认为下面的脚本做同样的事情,第二个应该快得多,因为第一个使用cat
需要一遍又一遍地打开文件但第二个只打开文件一次,然后只回显一个变量:
(有关正确的代码,请参阅更新部分。)
第一的:
#!/bin/sh
for j in seq 10; do
cat input
done >> output
Run Code Online (Sandbox Code Playgroud)
第二:
#!/bin/sh
i=`cat input`
for j in seq 10; do
echo $i
done >> output
Run Code Online (Sandbox Code Playgroud)
而输入大约是 50 兆字节。
但是当我尝试第二个时,它太慢了,因为回显变量i
是一个巨大的过程。我也遇到了第二个脚本的一些问题,例如输出文件的大小低于预期。
我还检查了手册页echo
并cat
比较了它们:
echo - 显示一行文本
cat - 连接文件并在标准输出上打印
但我没有得到区别。
所以:
i
?(因为在它的手册页中
echo
说它显示“一行文本”,所以我猜它只针对短变量进行了优化,而不是像 那样非常长的变量i
。然而,这只是一个猜测。)echo
?我用seq 10
而不是`seq 10`
错误的。这是编辑后的代码: …
除了使用临时文件来提供帮助之外,是否有一种方法/程序可以缓冲输入,stdin
但在获取EOF
. 我也不想使用 shell 变量(例如buffer=$(cat)
)。
该程序应如下所示(假设程序名称为buffered-cat
):
$ buffered-cat
line 1
line 2
line 3
^D # Ctr-D here(End of Line)
Run Code Online (Sandbox Code Playgroud)
现在程序收到了^D
,buffered-cat
输出内容
line 1
line 2
line 3
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 sed 将文件中的模式替换为另一个文件的完整内容。
目前我正在使用:
sed "s/PATTERN/`cat replacement.txt`/g" "openfile.txt" > "output.txt"
Run Code Online (Sandbox Code Playgroud)
但是,如果替换文件包含任何字符,例如'
, "
, 或者/
由于输入未经过清理而开始出现错误。
我一直在尝试使用本指南来帮助我,但我发现很难遵循。如果我尝试建议的r file
命令,我只会得到一个字符串。
解决这个问题的最佳方法是什么?
此脚本一行接一行地接受用户输入,并myfunction
在每一行上执行
#!/bin/bash
SENTENCE=""
while read word
do
myfunction $word"
done
echo $SENTENCE
Run Code Online (Sandbox Code Playgroud)
要停止输入,用户必须按[ENTER]
,然后按Ctrl+D
。
如何重建我的脚本以仅结束Ctrl+D
并处理Ctrl+D
按下的行。
我想测试一个相对符号链接是否指向某个目录的子树。
这个例子会产生,false
因为它指向foo
目录之外:
/foo>readlink bar
../fie.txt
虽然这个例子会产生true
:
/foo>readlink bar
fum/fie.txt
是否有我可以利用的现有实用程序,或者我必须从头开始编写代码?我正在使用bash
.
给定任意两个绝对 Unix 路径规范1,可以将每个规范分解为最长公共前缀和特定后缀的串联。例如,
/abc/bcd/cdf -> /abc/bcd + cdf
/abc/bcd/chi/hij -> /abc/bcd + chi/hij
Run Code Online (Sandbox Code Playgroud)
是否有 Unix 实用程序(或多个实用程序)来计算这种分解?(我添加了“或实用程序”,以防有用于计算最长公共前缀和计算相对路径的单独实用程序。)
(我意识到编写此类实用程序并不是非常困难,但我尽量优先使用或多或少标准的工具而不是定制的工具。)
1我写了“路径规范”而不是“路径”来回避给定文件系统、链接等中的(路径的)存在等问题。