shell_呈现数据

什么时候要使用&符号呢!!

我的理解是:当要输出重定向时,>*  这边加&

exec 3>&1    是输出到1,所以要&

exec 1>&3    输出到 3 

---

exec 6<&0   这是输入重定向,<* 加&

exec 0<&6    

以上说法对吗???

exec 的用法???



考虑重定向

标准输出和标准输入

报告错误

舍弃数据

创建日志文件

========================

标准文件描述符:linux用文件描述符来标识每个文件对象!文件描述符是个非负整数,可以唯一的标识会话中打开的文件。

bash  shell中保留了三个特殊的文件描述符。

0   STDIN      标准输入

只输入cat 本身

[oh@localhost shell]$ cat
fu
fu
fellow
fellow
EFO
EFO
EOF
EOF
EXIT
EXIT
QUIE
QUIE
^C
[oh@localhost shell]$ 

1 STDOUT   标准输出

2 STDERR    标准错误

ls -al badfiel 2> test4

[oh@localhost shell]$ ls -l ddddddddd
ls: cannot access ddddddddd: No such file or directory
[oh@localhost shell]$ ls -l ddddd 2> error.md
[oh@localhost shell]$ cat error.md 
ls: cannot access ddddd: No such file or directory
[oh@localhost shell]$ 

---------

ls -l filea fileb filec 2> error.md 1>ok.md

将错误重定向到error.md 将stdin到ok.md

或者 输出到同一个文件:  &> ok.md

==================

脚本中重定向输出:

1.临时重定向每行输出

2.永久重定向脚本中的命令


将echo "error error error" 重定向到文件

echo "eoor" >&2     //将单独的一行输出到STDERR。

然后再重定向:  ./c 2> error.md

[oh@localhost shell]$ cat now.md 
how are you
[oh@localhost shell]$ cat c
#!/bin/bash
#using redirect in shell script

ls / 1> now.md
(echo "how are you" >&2) 2> now.md
[oh@localhost shell]$ 

永久重定向:

exec 1>testout

则在执行期间会重定向某个特定的文件描述符。。。

所有的都会重定向!!!!

exec命令:

[oh@localhost shell]$ ./c
hi,oh the start of shell script
now redirecting all output to another location
[oh@localhost shell]$ cat c
#!/bin/bash
#using redirect in shell script

exec 2> testerror

echo "hi,oh the start of shell script"
echo "now redirecting all output to another location"

exec 1>testout

echo "this out put should go to testout"
echo "go now" >&2
[oh@localhost shell]$ cat testerror 
go now
[oh@localhost shell]$ cat testout 
this out put should go to testout
[oh@localhost shell]$ 

=============

在脚本中重定向输入!!

exec 0<file1

while read line

do

echo “ $line”

done

首先,stdin 被重定向到file1了

然后read是到stdin里读命令,也就是file1了。

===========

创建自己的重定向!!!


输出重定向

exec 3>test

echo "dfddf" >&3

------

输入重定向:

exec 6<&0

========

这一般用来当你改变了输入或是输出的重定向时,先用自定义文件描述符来保存原先位置,当一切搞好了后,再复原。

exec 3>&1    //先将文件描述符3定向到stdout
exec 1>test1     //再stdin定向到test1里,但是3仍然指向stdout
....
exec 1>&3     //再把1也就是test1,返回到3,也就是stdout
 

先将文件描述符3定向到stdin

再stdin定向到test1里

但是3仍然指向stdin

===============

exec 6<&0    //6重定向到0文件描述符,也就是stdin

exec 0<testfile    //stdin被重定向到testfile

exec 0<&6    //   0再被重定向到6,也就是stdin

==============

创建读写文件描述符:

[oh@localhost shell]$ cat ca
#!/bin/bash
#testing input/output file descriptor

exec 3<> testfile
read line<&3
echo "Read: $line"
echo "This is a test line">&3


[oh@localhost shell]$ cat testfile
This is a test line
[oh@localhost shell]$ vim testfile
[oh@localhost shell]$ cat testfile 
this is the first line
this is the second line
this is the third line
this is the end line
[oh@localhost shell]$ ./ca
Read: this is the first line
[oh@localhost shell]$ cat testfile
this is the first line
This is a test line
ine
this is the third line
this is the end line
[oh@localhost shell]$ 

 

由于你在向同一个文件进行读取数据,写入数据操作,shell会维护一个内部指针,指明现在在文件的什么位置。

任何读或写都会在文件指针上次保存的位置开始。

现在,read命令从testfile里读取了一行,文件指针指向了第二行数据的第一个字符,echo命令向其中写入数据,覆盖

了该指针位置的所有数据。。。

那么ine 是怎么回事???????

原来是写入是按字符个数覆盖文件指针的位置。

[oh@localhost shell]$ cat testfile 
this is the first line
This is the second line 
this is the third line
this is the end line
[oh@localhost shell]$ cat ca
#!/bin/bash
#testing input/output file descriptor

exec 3<> testfile
read line<&3
echo "Read: $line"
echo "This is a test">&3


[oh@localhost shell]$ ./ca
Read: this is the first line
[oh@localhost shell]$ cat testfile 
this is the first line
This is a test
ond line 
this is the third line
this is the end line
[oh@localhost shell]$ 

this is the second line\0共23个字符

this is a test\0  14个字符

14个字符对应------》就变成了 cond line\0

由于字符串结束标志是\0 所以多覆盖了一个c------------》ond line\0

我猜是这样的!!!!!!!!!

--------------

现在你想在脚本当中关闭文件描述符,使用  &-

exec 3>&-

-------

既然关闭了,就不能再使用了。

然后要使用的话,就得再次重新打开来!!!打开之后,得小心是再写入时会覆盖原有数据的!!!

==========

列出打开的文件描述符!!!

首先,只有九个文件描述符可用。而知道哪个文件描述符被重定向到哪里很难。

使用 /usr/sbin/lsof  命令来查看

lsof 会有大量输出,显示了当前linux系统上打开的每个文件的有关信息。包括后台运行的所有进程以及登录到系统的任何用户。

所以:

lsof -a -p $$ -d 0,1,2

-a:对其它两个选项的结果执行布尔and运算。

-p:允许指定进程ID,要知道该进程的当前PID,可以使用$$变量

-d:指定要显示的文件描述符个数

[oh@localhost shell]$ lsof -a -p $$ -d 0,1,2
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
bash    3865   oh    0r   CHR  136,1      0t0    4 /dev/pts/1    终端设备名
bash    3865   oh    1u   CHR  136,1      0t0    4 /dev/pts/1
bash    3865   oh    2u   CHR  136,1      0t0    4 /dev/pts/1
[oh@localhost shell]$ 

可以看到有7列:

command:正在运行命令的名字的前九个字符

FD:文件描述符数目及访问类型 (u代表读写)

TYPE:文件的类型(chr:字符型,blk:快型,dir:目录,reg:常规文件)

DEVICE:主设备号,从设备号

NODE:本地文件的节点数

SIZE:如果有的话,文件的大小

name:文件名

==========

使用 /dev/null

eg:

ls -al s dfdf dfd f 2> /dev/null

eg:

cat /dev/null >testfile    将testfile清空!!!!但是不删除文件。

=========

创建临时文件:

在/tmp目录下的东西在开机时会自动删除。

使用 mktemp命令可以在/tmp目录下创建文件。


在本地创建一个临时文件,你需要指定一个文件名模板。

mktemp testing.xxxxxx/必须是大写

6个X,X之后会被字符替换,它可以保证每个文件名都是唯一的。

[oh@localhost shell]$ mktemp testing.xxxxxx
mktemp: too few X's in template `testing.xxxxxx'
[oh@localhost shell]$ mktemp testing.XXXXXX
testing.ChmF1Y
[oh@localhost shell]$ ls -l testing.*
-rw-------. 1 oh oh 0 Apr 17 18:14 testing.ChmF1Y
[oh@localhost shell]$ 

在脚本中使用:

tempfile=`mktemp test.XXXXXX`


exec 3>$tempfile

=====

在/tmp 目录下创建临时文件

-t  选项

[oh@localhost shell]$ mktemp -t aaa.XXXXXX
/tmp/aaa.RfCZ1h
[oh@localhost shell]$ 

临时目录:  -d

temdir=`mktemp -d dir.XXXXXX`

cd $temdir

------------

记录消息:tee命令

tee想一个T型接头

这样就既可以将数据显示到显示器,又可以保存到文件里

stdin 的数据发往两个目地的

tee filename

date | tee file


tee 默认会覆盖file内容

tee -a  追加到文件后面。




















































阅读更多
个人分类: linux
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭