【发布时间】:2015-07-12 13:24:42
【问题描述】:
我知道在管道末尾设置的任何变量都会丢失(不包括 Bash 4 中的 shell 选项 - 不幸的是,这需要是一个可移植的解决方案)。但是,我确信必须有一种方法使用文件描述符或其他东西将管道末端的输出流式传输到变量中,即使通过一些复杂的路由! :)
理想情况下,我想要一个带有一个参数的命令/函数,一个变量的名称,最终将导致包含管道其余部分的输出。
我有一个函数可以以可移植的方式找到它的下一个空闲文件描述符:
getFd ()
{
# we'll start with 3 since 0..2 are mapped to standard in, out, and error respectively
local myFD='3'
# we'll get the upperbound from bash's ulimit
local FD_MAX=$( ulimit -n )
local FD_LOC
if [ -e /proc/$$/fd ]
then
FD_LOC="/proc/$$/fd"
elif [ -e /dev/fd ]
then
FD_LOC="/dev/fd"
else
return 1
fi
while [ -e "${FD_LOC}/${myFD}" ] && [ "${myFD}" -le "${FD_MAX}" ]
do
((++myFD))
done
eval FD="${myFD}"
}
我想我可能需要做一些事情,比如以前创建一个打开的文件描述符池,可以通过一些别名 jiggery pokey 或其他东西拉入,但我希望我错过了一些更简单的方法,因为我确信必须有做一个更好的方法。
我还在想,如果我在末尾添加printf %s "${myFD}",我可以执行alias '{FD}'="$( getFd )" 之类的操作来实现自动查找下一个可用文件描述符以{FD} <filename 形式使用的Bash 4 功能注意:需要有一个空间,但是如果可以使它起作用,那么将这个特性带到 bash 3.0 中会很棒。另外,可能必须使用shopt -s expand_aliases。
任何想法将不胜感激!
附:我试图避免强制使用 MyCommand MyVariable < <( command1 | command2 ; ) ; 类型语法,并且我正在努力是否可以以:$ command1 | command2 | MyCommand MyVariable ; 使用类型结束。
【问题讨论】:
-
您似乎正在尝试做一些对于 shell 脚本来说太复杂的事情。考虑改为编写 Perl 或 Python 脚本。
-
你的问题听起来很有趣,但并不容易理解。以下是您的读者可能会问自己的一些问题:为什么这些变量会丢失?你在说什么外壳选项?管道的哪一端——我以为他们有两个?他们为什么不直接使用命令替换?这能解决什么问题还是只是语法糖?
-
该功能是如何工作的?
FD_LOC中的$$没有在我能看到的任何地方展开。还有为什么eval在最后一行? -
我假设您想要的不仅仅是让函数将内容写入预先安排的(或通过数字传递的)fd,然后在下一行读取?您想为此获得所需的运行环境有多“棘手”?我认为您无法让命令本身执行此操作,因此您需要环境中的 something 在某处进行变量设置。
-
嘿,$$ 是一个标准的“特殊”bash 变量(我相信也是 Bourne),它为您提供了评估时所处的 shell 的 PID。这与那些使用
/proc文件系统来确定下一个可用fd 的结构有关,因为结构是/proc/<pid>/fd/<fd>,其中<pid>是shell 的pid,而是驻留在那里的文件描述符文件。这是一种语法糖,尽管我正在使用它来构建一种更友好和更明智的方式,通过一些非常需要的语言扩展来处理 shell。 :)
标签: linux bash shell unix scripting