GVKun编程网logo

bash – 关于FIFO和文件描述符的问题(bash if fi)

13

本文将分享bash–关于FIFO和文件描述符的问题的详细内容,并且还将对bashiffi进行详尽解释,此外,我们还将为大家带来关于bash–使用链接到stdin的文件描述符的原因而不是直接使用stdi

本文将分享bash – 关于FIFO和文件描述符的问题的详细内容,并且还将对bash if fi进行详尽解释,此外,我们还将为大家带来关于bash – 使用链接到stdin的文件描述符的原因而不是直接使用stdin?、bash – 写入文件描述符3而不写入磁盘?、bash – 创建文件描述符然后回显它的重点是什么、bash – 如何关闭unix系统中另一个进程的文件描述符的相关知识,希望对你有所帮助。

本文目录一览:

bash – 关于FIFO和文件描述符的问题(bash if fi)

bash – 关于FIFO和文件描述符的问题(bash if fi)

我写了一个这样的脚本:

N=5
FIFO=/tmp/$$.fifo
mkfifo $FIFO

loop(){
    for i in $(seq 1 $N); do
        read tmp < $FIFO
        echo "$i out"
    done
}

loop &
LOOP_PID=$!
for i in $(seq 1 $N); do
    echo $i > $FIFO
    echo "$i in"
done
wait $LOOP_PID

当我运行脚本时,它停止等待$LOOP_PID并且无法继续.

所以我用文件描述符修改脚本:

N=5
FIFO=/tmp/$$.fifo
mkfifo $FIFO
exec 3<>$FIFO

loop(){
    for i in $(seq 1 $N); do
        read -u3 tmp
        echo "$i out"
    done
}

loop &
LOOP_PID=$!
for i in $(seq 1 $N); do
    echo $i >&3
    echo "$i in"
done
wait $LOOP_PID

还可以.

当我直接使用FIFO时,它无法连续从FIFO中读取数据,它会挂起.当我使用文件描述符时,它没关系.是什么原因?

解决方法

替换这个:

loop(){
    for i in $(seq 1 $N); do
        read tmp < $FIFO
        echo "$i out"
    done
}

有了这个:

loop(){
    for i in $(seq 1 $N); do
        read tmp
        echo "$i out"
    done < $FIFO
}

这使得fifo保持打开状态,而不是每次循环重新打开并重新关闭它.

FIFO非常棘手:

>除非另一个进程准备好从FIFO读取,否则尝试写入FIFO将被阻止.
>如果从FIFO读取的进程关闭FIFO,则任何未读信息都将丢失.

这意味着上述脚本的行为方式可能取决于计时事故.当读取tmp< $FIFO正在执行,有多少行写入FIFO? read将只读取第一个,当FIFO关闭时,其余的将被丢弃. exec语句如何帮助 我们来比较两个脚本.第一个直接使用FIFO:

#!/bin/sh
fifo=/tmp/$$.myfifo
mkfifo "$fifo"
echo $'1\n2\n3\n4'>"$fifo"

for i in {1..4}
do
    read  tmp
    echo $tmp
done <"$fifo"

在等待进程开始读取FIFO时,上述脚本将在第一个回显期间挂起.因为它挂起,所以永远不会到达读取tmp语句,并且此脚本不会产生任何输出.

第二个使用exec来创建文件句柄:

#!/bin/sh
fifo=/tmp/$$.myfifo
mkfifo "$fifo"
exec 3<>"$fifo"
echo $'1\n2\n3\n4'>&3

for i in {1..4}
do
    read -u3 tmp
    echo $tmp
done

此脚本不会挂起并将生成四行输出.不同之处在于shell为文件句柄提供缓冲.因此,当第一个echo语句尝试写入FIFO时,shell已准备好从FIFO读取. shell读取的数据可用于读取-u3 tmp语句.

bash – 使用链接到stdin的文件描述符的原因而不是直接使用stdin?

bash – 使用链接到stdin的文件描述符的原因而不是直接使用stdin?

我有一个bash脚本,它以下列方式启动scp:

echo "${SCP_PASS:-$PASSWORD}" | ( exec 3<&0; scp -qp ${SCP_PORT:+-P$SCP_PORT} -oStrictHostKeyChecking=yes -oPasswordFd=3 $TRANSFER_FILE "$SCP_USER@$SCP_HOST:$SCP_PATH" )

exec 3<& 0>的重点是什么?据我所知,它将stdin复制到文件描述符3.为什么需要它?为什么不使用-oPasswordFd = 0?

解决方法

将stdin重定向到fd 3没有任何好处 – 而且PasswordFd似乎也不是一个openssh选项 – 似乎正在运行的scp是一个包装器或自定义构建 – 通常虽然在单独的文件描述符上提供密码的好处是保持stdin打开数据传输btw openssh scp不支持

bash – 写入文件描述符3而不写入磁盘?

bash – 写入文件描述符3而不写入磁盘?

有没有办法与文件描述符交互而无需在磁盘上打开文件?

如果没有首先将文件分配给fd3,这将无法工作:

echo a >&3

解决方法

取决于你想做什么.假设您想在闲暇时写字符串并将其反转打印.设置文件描述符重定向到等待stdin的进程替换:

$exec 3> >(rev)
$echo hello world >&3
dlrow olleh

完成后,您可以关闭文件描述符

$exec 3>&-
$echo hello world >&3
bash: 3: Bad file descriptor

bash – 创建文件描述符然后回显它的重点是什么

bash – 创建文件描述符然后回显它的重点是什么

我在一些 Linux bash脚本中看到,例如autoconf生成的配置脚本,这样的序列

exec 5>>config.log

(……)

echo foo >&5

(……)

echo bar >&5

(重复多次)

在我看来,人们可以做到

echo foo >>config.log

这更简单.那么用exec做这件事有什么意义呢.必须有一些我不理解的理由.它是什么?

解决方法

方便.如果您的目标日志文件名称发生更改,则您将不得不搜索&替换所有实例.这很烦人.您可以使用变量来缓解这种情况:

$LOGFILE=config.log
echo foo>>$LOGFILE

性能.每一行,bash都要扩展LOGFILE – 需要时间.然后bash必须打开文件 – 需要花费很多时间.然后bash可以写到它.然后bash终于fclose了.因此,当你使用字符串而不是文件描述符时,bash必须做大量的工作来将数据填充到文件中.一次性,两次性,这不是什么大不了的事.这样做数百次,数千次? It adds up.

灵活性.将文件描述符分配给文件描述符后,可以执行interesting things:

>将其重定向到其他地方>将其复制到其他地方(如stderr)>永久关闭它>将其作为过滤器的一部分应用

bash – 如何关闭unix系统中另一个进程的文件描述符

bash – 如何关闭unix系统中另一个进程的文件描述符

您可以使用命令lsof获取所有正在运行的进程的文件描述符,但我想要做的是关闭一些描述符,而不必在该进程内。这可以在Windows上完成,所以你可以轻松地解除阻塞一些应用程序。

有什么命令或功能吗?

在Windows中,您可以使用程序来执行此操作,因为有人编写了一个将设备驱动程序插入运行的内核中的程序。顺便说一句,这样做可能是危险的,因为关闭一个破坏的应用程序正在使用的句柄,应用程序不知道该句柄被关闭,当应用程序打开一些其他不相关的对象,它不知道相同的句柄现在可以引用一些其他不相关的对象。你真的想要尽快杀死破碎的应用程序。

在Linux中肯定你可以使用同样的技术。编写一个将模块插入正在运行的内核中的程序。与模块通信并告诉它要关闭哪些句柄。这样做同样是危险的。

关于bash – 关于FIFO和文件描述符的问题bash if fi的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于bash – 使用链接到stdin的文件描述符的原因而不是直接使用stdin?、bash – 写入文件描述符3而不写入磁盘?、bash – 创建文件描述符然后回显它的重点是什么、bash – 如何关闭unix系统中另一个进程的文件描述符等相关知识的信息别忘了在本站进行查找喔。

本文标签: