Linux shell中管道(|)与重定向(<or>) 及动态链接库中函数查找
管道(|)与重定向(< or >)
管道(|)
![](https://i-blog.csdnimg.cn/blog_migrate/af2aaad0d7904c72a48b59f11275060b.png)
[chengmo@centos5 shell]$ cat test.sh test1.sh | grep -n 'echo'
cat: test1.sh: 没有那个文件或目录
5: echo "very good!";
#cat test1.sh不存在,错误输出打印到屏幕,正确输出通过管道发送给grep
[chengmo@centos5 shell]$ cat test.sh test1.sh 2>/dev/null | grep -n 'echo'
5: echo "very good!";
#将test1.sh 没有找到错误输出重定向输出给/dev/null 文件,正确输出通过管道发送给grep
重定向(>or<)
左边的命令有标准输出(>)或者是接受标准输入(<),所以左边一定是指令,而右边只能是文件。
不同于管道,1. 管道是左边的命令应该有标准的输出,右边的命令应该接受标准输入;
2. 管道触发两个子进程执行“|”两边的程序,而重定向是单进程;
3. 重定向的优先级高于管道。
[chengmo@centos5 shell]$ (sed -n '1,$p'|grep -n 'echo')<test.sh
5: echo "very good!";
7: echo "good!";
9: echo "pass!";
11: echo "no pass!";
#这个脚本比较有意思了。由于前面是管道,后面需要把test.sh内容重定向到 sed ,然后sed输出通过管道,输入给grep.需要将前面用"()"运算符括起来。在单括号内的命令,可以把它们看作一个象一个命令样。如果不加括号test.sh就是grep 的输入了。
#上面一个等同于这个
[chengmo@centos5 shell]$ sed -n '1,$p'<test.sh | grep -n 'echo'
5: echo "very good!";
7: echo "good!";
9: echo "pass!";
11: echo "no pass!";
#重定向运算符,在shell命令解析前,首先检查的(一个命令,执行前一定检查好它的输入,输出,也就是0,1,2 设备是否准备好),所以优先级会最高
[chengmo@centos5 shell]$ sed -n '1,10p'<test.sh | grep -n 'echo' <testsh.sh
10:echo $total;
18:echo $total;
21: echo "ok";
#哈哈,这个grep又接受管道输入,又有testsh.sh输入,那是不是2个都接收呢。刚才说了"<"运算符会优先,管道还没有发送数据前,grep绑定了testsh.sh输入,这样sed命令输出就被抛弃了。这里一定要小心使用
#输出重定向
[chengmo@centos5 shell]$ cat test.sh>test.txt
[chengmo@centos5 shell] cat test.sh|tee test.txt &>/dev/null
#通过管道实现将结果存入文件,还需要借助命令tee,它会把管道过来标准输入写入文件test.txt ,然后将标准输入复制到标准输出(stdout),所以重定向到/dev/null 不显示输出
#">"输出重定向,往往在命令最右边,接收左边命令的,输出结果,重定向到指定文件。也可以用到命令中间。
[chengmo@centos5 shell]$ ls test.sh test1.sh testsh.sh 2>err.txt | grep 'test'
test.sh
testsh.sh
#目录下面有:test,testsh文件,test1.sh不存在,因此将ls 命令错误输出输入到err.txt 正确输出,还会通过管道发送到grep命令。
[chengmo@centos5 shell]$ ls test.sh test1.sh testsh.sh &>err.txt | grep 'test'
#这次打印结果是空,&代表正确与错误输出 都输入给err.txt,通过管道继续往下面传递数据为空,所以没有什么显示的
#同样">"输出重定向符,优先级也是先解析,当一个命令有这个字符,它就会与左边命令标准输出绑定。准备好了这些,就等待命令执行输出数据,它就开始接收
用户程序作为指令:
#include <iostream>
int main()
{
std::string str;
std::cin>>str;
std::cout<<str<<std::endl;
}
~
cat < ./test.txt | ./a.out
分析:重定向将文件test.txt文件的内容输入到cat指令,cat指令可以接受stdin数据,然后cat将数据通过通道传到指令./a.out中,a.out中有std::cin接受标准的输入,故可以接受管道参数,然后讲数据输出。
动态链接库中查找函数的应用
代码:
用nm指令:
nm -D library_name.so | grep "functionname*"
用readelf指令:
readelf -a library_name.so | grep "functionname*"
使用find也可以帮助查找库的位置
find dir -name "*name*"
结合xargs查找文件内容
find ./include/opencv* -name "*.hpp" | xargs grep "sdot_*"
在文件夹./include/opencv*中找到所有头文件,并通过通道传到右边的命令,右边的命令通过xargs将传来的stdin输入参数化,作为grep指令的参数输入,grep根据这些文件,在其中查找字符串“sdot_*”字符串。
xargs命令是给其他命令传递参数的一个过滤器,也是组合多个命令的一个工具。它擅长将标准输入数据转换成命令行参数,xargs能够处理管道或者stdin并将其转换成特定命令的命令参数。xargs也可以将单行或多行文本输入转换为其他格式,例如多行变单行,单行变多行。xargs的默认命令是echo,空格是默认定界符。这意味着通过管道传递给xargs的输入将会包含换行和空白,不过通过xargs的处理,换行和空白将被空格取代。xargs是构建单行命令的重要组件之一。
参考:
http://www.jb51.net/LINUXjishu/32565.html
http://man.linuxde.net/xargs