为/ dev /标准输入与herestring [英] /dev/stdin with herestring

查看:215
本文介绍了为/ dev /标准输入与herestring的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想一个bash脚本,可以输入从文件或标准输入,就像的grep ,例如:

$猫hw.txt
你好,世界$ grep的WOR hw.txt
你好,世界$回声世界,你好| grep的WOR
你好,世界$ grep的WOR<<< '你好,世界'
你好,世界

所有精美的作品。然而,随着下面的脚本

 查看B< $ {1-的/ dev /标准输入}
回声$ B

它如果使用herestring失败

$ hw.sh hw.txt
你好,世界$回声世界,你好| hw.sh
你好,世界$ hw.sh<<< '你好,世界'
/opt/a/hw.sh:1号线:为/ dev /标准输入:没有这样的文件或目录


解决方案
使用的/ dev /标准输入

由于您正试图获得一个句柄以这种方式可能会产生问题标准输入在文件系统中使用的名称(的/ dev /标准输入),而不是使用的庆典已经交给你作为标准输入(文件描述符0)的文件描述符。

下面是一个小脚本,为您的测试:

 #!/斌/庆典回声信息是:/ dev列表
LS -al的/ dev /标准输入回声INFO:的/ proc /自/ FD列表
LS -al的/ proc /自/ FD回声信息:/ tmp目录/ SH-THD *的内容。
猫的/ tmp / SH-THD *查看B< $ {1-的/ dev /标准输入}
回声B:$ B

在我的Cygwin安装这将产生以下内容:

  ./ S<<< '你好,世界'
$ ./s<<< '你好,世界'
信息:上市的/ dev
lrwxrwxrwx 1奥斯汀无23年1月15日2012 /开发/标准输入 - >的/ proc /自/ FD / 0
INFO:的/ proc /自/ FD上市
共0
DR-XR-XR-X 2奥斯汀无0 03月11日14:27。
DR-XR-XR-×3奥斯汀无0 03月11日14:27 ..
lrwxrwxrwx 1奥斯汀无0 3月11日14:27 0 - >的/ tmp / SH-THD-1362969584
lrwxrwxrwx 1奥斯汀无0 3月11日14:27,第1 - >为/ dev / tty0的
lrwxrwxrwx 1奥斯汀无0 3月11日14:27 2 - >为/ dev / tty0的
lrwxrwxrwx 1奥斯汀无0 3月11日14:27 3 - >的/ proc / 5736 / FD
INFO:/ tmp目录/ SH-THD的内容*
猫:/ tmp目录/ SH-THD *:没有这样的文件或目录
./s:第12行是:/ dev /标准输入:没有这样的文件或目录
乙:

这是什么输出显示的是bash的是创建一个临时文件来保存您的HERE文档(的/ tmp / SH-THD-1362969584 ),并使其可文件描述符0,标准输入。然而,临时文件已经从文件系统链接断开,所以不是通过文件系统名称引用访问,如的/ dev /标准输入。您可以通过尝试打开读文件描述符0获得内容,而不是的/ dev /标准输入

在Linux上, ./小号上面的脚本给出以下,显示出该文件已被取消链接:

 信息是:/ dev上市
lrwxrwxrwx 1根根11年3月15日09:26为/ dev /标准输入 - >的/ proc /自/ FD / 0
INFO:的/ proc /自/ FD上市
共0
博士-X ------ 2奥斯汀0 03月11日14:30。
DR-XR-XR-x 7的奥斯汀0 03月11日14:30 ..
LR-X ------ 1奥斯汀64年3月11 14:30 0 - >的/ tmp / SH-THD-1362965400(删除)< ----为/ dev /标准输入未找到
lrwx ------ 1奥斯汀64年3月11 14:30 1 - >为/ dev / PTS / 12
lrwx ------ 1奥斯汀64年3月11 14:30 2 - >为/ dev / PTS / 12
LR-X ------ 1奥斯汀64年3月11 14:30 3 - >的/ proc / 10659 / FD
INFO:/ tmp目录/ SH-THD的内容*
猫:/ tmp目录/ SH-THD *:没有这样的文件或目录
A:你好世界

更改您的脚本使用标准输入提供的,而不是试图通过的/ dev /标准输入引用。

 如果[-n$ 1];然后
    查看B< $ 1
其他
    查看b
科幻

I would like a Bash script that can take input from a file or stdin, much like grep, for example

$ cat hw.txt
Hello world

$ grep wor hw.txt
Hello world

$ echo 'Hello world' | grep wor
Hello world

$ grep wor <<< 'Hello world'
Hello world

all works beautifully. However with the following script

read b < "${1-/dev/stdin}"
echo $b

It fails if using a herestring

$ hw.sh hw.txt
Hello world

$ echo 'Hello world' | hw.sh
Hello world

$ hw.sh <<< 'Hello world'
/opt/a/hw.sh: line 1: /dev/stdin: No such file or directory

解决方案

Using /dev/stdin in this manner can be problematic because you are attempting to get a handle to stdin using a name in the filesystem (/dev/stdin) rather than using the file descriptor which bash has already handed you as stdin (file descriptor 0).

Here's a small script for you to test:

#!/bin/bash

echo "INFO: Listing of /dev"
ls -al /dev/stdin

echo "INFO: Listing of /proc/self/fd"
ls -al /proc/self/fd

echo "INFO: Contents of /tmp/sh-thd*"
cat /tmp/sh-thd*

read b < "${1-/dev/stdin}"
echo "b: $b"

On my cygwin installation this produces the following:

./s <<< 'Hello world'


$ ./s <<< 'Hello world'
INFO: Listing of /dev
lrwxrwxrwx 1 austin None 15 Jan 23  2012 /dev/stdin -> /proc/self/fd/0
INFO: Listing of /proc/self/fd
total 0
dr-xr-xr-x 2 austin None 0 Mar 11 14:27 .
dr-xr-xr-x 3 austin None 0 Mar 11 14:27 ..
lrwxrwxrwx 1 austin None 0 Mar 11 14:27 0 -> /tmp/sh-thd-1362969584
lrwxrwxrwx 1 austin None 0 Mar 11 14:27 1 -> /dev/tty0
lrwxrwxrwx 1 austin None 0 Mar 11 14:27 2 -> /dev/tty0
lrwxrwxrwx 1 austin None 0 Mar 11 14:27 3 -> /proc/5736/fd
INFO: Contents of /tmp/sh-thd*
cat: /tmp/sh-thd*: No such file or directory
./s: line 12: /dev/stdin: No such file or directory
b: 

What this output shows is that bash is creating a temporary file to hold your HERE document (/tmp/sh-thd-1362969584) and making it available on file descriptor 0, stdin. However, the temporary file has already been unlinked from the file system and so is not accessible by reference through a file system name such as /dev/stdin. You can get the contents by reading file descriptor 0, but not by trying to open /dev/stdin.

On Linux, the ./s script above gives the following, showing that the file has been unlinked:

INFO: Listing of /dev
lrwxrwxrwx 1 root root 15 Mar 11 09:26 /dev/stdin -> /proc/self/fd/0
INFO: Listing of /proc/self/fd
total 0
dr-x------ 2 austin austin  0 Mar 11 14:30 .
dr-xr-xr-x 7 austin austin  0 Mar 11 14:30 ..
lr-x------ 1 austin austin 64 Mar 11 14:30 0 -> /tmp/sh-thd-1362965400 (deleted) <---- /dev/stdin not found
lrwx------ 1 austin austin 64 Mar 11 14:30 1 -> /dev/pts/12
lrwx------ 1 austin austin 64 Mar 11 14:30 2 -> /dev/pts/12
lr-x------ 1 austin austin 64 Mar 11 14:30 3 -> /proc/10659/fd
INFO: Contents of /tmp/sh-thd*
cat: /tmp/sh-thd*: No such file or directory
b: Hello world

Change your script to use the stdin supplied, rather than trying to reference through /dev/stdin.

if [ -n "$1" ]; then
    read b < "$1"
else
    read b
fi

这篇关于为/ dev /标准输入与herestring的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆