unix bash在if-statement中使用STDIN

u4dcyp6a  于 11个月前  发布在  Unix
关注(0)|答案(2)|浏览(68)

如果stdin不等于特定文件,有没有一种方法可以输出错误?举例来说:我希望我的stdin等于test.txt

./script.sh < test.txt # should run

字符串
但是

./script.sh < wrong.txt # shouldn't run


有办法做到这一点吗?像这样的东西?

if [ STDIN != "test.txt" ]
then 
echo "Error: stdin should be able to test.txt"
fi

ldioqlga

ldioqlga1#

linux上,是的,但它不是可移植的:

#in a POSIX shell:
if [ "`readlink /dev/fd/0`" != "$PWD/test.txt" ]; then 
    >&2 echo "Error: stdin should be able to test.txt"
fi

字符串
这是因为在linux上,/dev/fd/0(或/proc/self/fd/0/proc/$$/fd/0(仅在shell中))是一个符号链接,指向表示标准输入的文件。

ldxq2e6h

ldxq2e6h2#

您必须检查文件处理程序0是否被重定向到您的文件。你可以这样做:

#!/bin/bash

me=$$
file=$(readlink -n /proc/$me/fd/0)
echo $file   
if [[ "$file" =~ /x.sh$ ]]; then echo YES
else echo NO
fi
# Alternate solution
if [[ "$file" == */x.sh ]]; then echo YES
else echo NO
fi
# Another alternate old style bash solution
# if [ "${file##*/}" = x.sh ]; then

字符串
首先,它得到正在运行的bash的PID。然后在virtual /proc文件系统中查找文件处理程序0。/proc/<PID>fd/中的每一项都是一个符号链接,readlink(1)可以读取。如果它没有被重定向,符号链接会链接到一个dev文件,如下所示:/dev/pts/6,如果它被重定向到终端,或者pipe:[33773],如果它是一个管道,或者socket:[36915],如果它是一个套接字(如/dev/tcp/ibm.com/80),或者/path/filename,如果文件被重定向。然后file必须匹配一个模式。在我的例子中,我测试了file是否等于x.sh
所以如果你打字

$ ./x.sh <x.sh; ./x.sh < y.sh


输出为

/home/truey/stackoverflow/x.sh
YES
YES
/home/truey/stackoverflow/y.sh
NO
NO

相关问题