大概尝试多次ssh访问,但在第一次读取后就被销毁了:fdfd
# ssh -i <(echo $KEY) user@example.com
Warning: Identity file /dev/fd/11 not accessible: Bad file descriptor.
user@example.com: Permission denied (publickey).
Run Code Online (Sandbox Code Playgroud)
有没有其他方法而不写入/删除临时文件?
这是我最常做的运行grep,并wc在一个文件,而无需扫描两次
<file.txt tee >(grep LITERAL) >(wc -l) >/dev/null
Run Code Online (Sandbox Code Playgroud)
然而,这会产生
EXEC LITERAL
32
Run Code Online (Sandbox Code Playgroud)
有时和
32
EXEC LITERAL
Run Code Online (Sandbox Code Playgroud)
在其他时间。(第一个实例中grepfrom的输出先于from的输出,wc在第二个实例中反之亦然。)
另一方面,使用重定向和文件描述符
{ { <file.txt tee /dev/fd/3 | grep LITERAL >&4; } 3>&1 | wc -l ;} 4>&1
Run Code Online (Sandbox Code Playgroud)
我似乎总是得到
EXEC LITERAL
32
Run Code Online (Sandbox Code Playgroud)
我更喜欢输出顺序是可预测的,但是第二种方法可以保证吗?
我正在尝试组合一些像这样的程序(请忽略任何额外的包含,这是正在进行的繁重工作):
pv -q -l -L 1 < input.csv | ./repeat <(nc "host" 1234)
Run Code Online (Sandbox Code Playgroud)
重复节目的来源如下所示:
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <iostream>
#include <string>
inline std::string readline(int fd, const size_t len, const char delim = '\n')
{
std::string result;
char c = 0;
for(size_t i=0; i < len; i++)
{
const int read_result = read(fd, &c, sizeof(c));
if(read_result != sizeof(c))
break;
else
{
result += c;
if(c == …Run Code Online (Sandbox Code Playgroud) 我很想知道流程替换已经存在了多长时间。什么外壳首先拥有它?它什么时候被添加到其他 shell 中的?
一些程序需要它们的文件是可查找的,例如objdump确实如此。
$ objdump -D -b binary -m i8086 <(echo 0xea 0x5b 0xe0 0x00 0xf0|xxd -r -p)
objdump: Warning: '/proc/self/fd/11' is not an ordinary file
Run Code Online (Sandbox Code Playgroud)
让进程替换使用临时文件会很方便。
我可以在手册页中看到 bash 可以使用进程替换回退到临时文件,但是我可以明确要求他使用临时文件吗?
喜欢zsh的=()。
$ objdump -D -b binary -m i8086 =(echo 0xea 0x5b 0xe0 0x00 0xf0|xxd -r -p)
/tmp/zsh1u1Nrw: file format binary
Disassembly of section .data:
00000000 <.data>:
0: ea 5b e0 00 f0 ljmp $0xf000,$0xe05b
Run Code Online (Sandbox Code Playgroud) 我正在尝试errpipe使用stderr通过过滤器运行的简单 api编写实用程序脚本。起初我尝试使用 bash 的进程替换功能来实现它。
#!/bin/bash
com="$1"
errpipe="$2"
$com 2> >(1>&2 $errpipe)
Run Code Online (Sandbox Code Playgroud)
这样做的问题是当com不存在时输出看起来很奇怪。
如果我输入
sh-3.2$ ./errpipe foo cat
Run Code Online (Sandbox Code Playgroud)
我得到
sh-3.2$ ./errpipe foo cat
sh-3.2$ ./errpipe: line 6: foo: command not found
@
Run Code Online (Sandbox Code Playgroud)
用@代表光标。换句话说,shell 提示打印得太早了。我怀疑这是因为主 shell 脚本没有等待进程替换过程完成。在wait脚本末尾添加a似乎并不能解决问题。
我打开一个解决方案,使用bash,ksh,zsh或可能有些疯狂的awk功能。我想我知道如何使用 C 或 Perl 之类的东西将它们连接在一起,这些东西公开了更丰富的 API 来操作进程和文件描述符,但我想避免使用它,除非没有替代方案。
一种“几乎有效”的解决方案是使用在$$shell fork 时没有改变的事实,并在 errpipe 完成时向父级发出信号。
#!/bin/bash
com="$1"
errpipe="$2"
$com 2> >(1>&2 $errpipe; kill -SIGUSR1 $$)
while true; do …Run Code Online (Sandbox Code Playgroud) 在 Bash 中,您可以重定向当前正在运行的脚本的所有未来stdout 输出。例如使用这个脚本,
exec > >(logger -t my-awesome-script)
echo 1
echo 2
echo 3
Run Code Online (Sandbox Code Playgroud)
这将在系统日志中结束:
Oct 26 01:03:16 mybox my-awesome-script[72754]: 1
Oct 26 01:03:16 mybox my-awesome-script[72754]: 2
Oct 26 01:03:16 mybox my-awesome-script[72754]: 3
Run Code Online (Sandbox Code Playgroud)
但这是 Bash 特定的,带有重定向的裸 exec 在 Dash 中似乎不起作用。
Syntax error: redirection unexpected
Run Code Online (Sandbox Code Playgroud)
我怎样才能让它在 Dash 中工作,或者可能在两个 shell 中工作?
我正在编写一个脚本来读取变量 a 和 b 的命令输出。这是脚本
#!/bin/bash
read a b < <(awk '/Application Server/ && !seen[$7]++{printf "%s ", $7}' /tmp/ServerState)
echo "The value of a is $a"
echo "The value of b is $b"
Run Code Online (Sandbox Code Playgroud)
并得到语法错误:
line 3: syntax error near unexpected token `<'
line 3: `read a b < <(awk /Application Server/ && !seen[$7]++{echo "%s ", $7} /tmp/ServerState)'
Run Code Online (Sandbox Code Playgroud)
但是当我在控制台中输入相同的命令时,它对我来说没有任何问题。
app@user:/tmp> read a b < <(awk '/Application Server/ && !seen[$7]++{printf "%s ", $7}' /tmp/ServerState)
app@user:/tmp> echo $a
FAILED
app@user:/tmp> echo $b
STARTED …Run Code Online (Sandbox Code Playgroud) 这是我的用例:命令行实用程序melt可以接受带有.melt命令行扩展名的文件名,然后打开它;例如,这是一个正确的test_p.melt文件:
colour:blue
out=24
colour:red
out=48
Run Code Online (Sandbox Code Playgroud)
... 打开并播放melt test_p.melt.
现在,问题是.melt文件不支持注释,我希望他们支持(对于包含不可解析参数的任何行,包括那些带有 a 的参数,您都会收到错误消息#)。所以这是一个注释test_c.melt文件:
# master comment here
colour:blue # this is blue!
out=24
colour:red
out=48
Run Code Online (Sandbox Code Playgroud)
melt直接打开它给出:
$ melt test_c.melt
Failed to load "# master comment here"
...
Run Code Online (Sandbox Code Playgroud)
...并且没有显示蓝屏。
所以我想 - 好吧,我无论如何都可以添加注释,然后使用 Bash 进程替换来过滤文件sed,然后简单地将其提供给melt应用程序。首先,尝试使用 进行测试cat,测试成功:
$ cat <(sed 's/#.*$//' test_c.melt)
colour:blue
out=24
colour:red
out=48
Run Code Online (Sandbox Code Playgroud)
... 看起来挺好的; 但是,如果我尝试使用melt,它会看穿我的诡计: …
在尝试输出重定向和进程替换时,我偶然发现了以下命令及其结果输出:
me@elem:~$ echo foo > >(cat); 回声条
酒吧
我@elem:~$ foo
(是的,最后那个空的换行符是故意的。)
所以 bash echo 的栏,打印我通常的提示,echo 的 foo,echo 是一个换行符,并将我的光标留在那里。如果我再次按回车键,它会在新行上打印我的提示并将光标留在后面(当有人在空命令行上按回车键时,正如预期的那样)。
我期待它将 foo 写入文件描述符,cat 读取它和 echo 的 foo,第二个 echo echo 的 bar,然后返回到命令提示符。但显然情况并非如此。
有人可以解释一下发生了什么吗?