天天看点

shell基础五:输入和输出(echo,read,cat,管道,tee,重定向等)

下面的所有环境都在在REDHAT LINUX9下试验的

在LINUX中,要使转义符生效,需加参数-e

从echo的变量开始说起

如:e c h o命令输出转义符以及变量。

                                                                      # echo -e "/007your home is $HOME , you are connected on `tty`"

your home is /root , you are connected on /dev/pts/1

# echo -e "/ayour home is $HOME , you are connected on `tty`"

your home is /root , you are connected on /dev/pts/1

#

  本例中

/007或/a你可以让终端铃响一声

显示出$ H O M E目录,

并且可以让系统执行t t y命令(注意,该命令用键盘左上角的符号,法语中的抑音符引起来,不是单引号 )。 在e c h o命令输出之后附加换行,可以使用/ n选项:

                                                                      $ cat echod

#!/bin/sh

echo -e "this echo's 3 new lines/n/n/n"

echo "OK" 编辑一个新echod,如上内容,然后运行输出如下:

                                                                      $ ./echod

this echo's 3 new lines

OK

$ 在e c h o语句中使用跳格符,记住别忘了加反斜杠/:

                                                                      $ echo -e "here is a tab/there are two tabs/t/tok"

here is a tab   here are two tabs               ok

$ 把一个字符串输出到文件中,使用重定向符号>。

在下面的例子中一个字符串被重定向到一个名为m y f i l e的文件中:

                                                                      $ echo "The log files have all been done"> myfile 或者可以追加到一个文件的末尾,这意味着不覆盖原有的内容:

                                                                      $ echo "$LOGNAME carried them out at `date`">>myfile 现在让我们看一下m y f i l e文件中的内容:

  The log files have all been done

sam carried them out at 六 11月 13 12:54:32 CST 2004 引号是一个特殊字符,所以必须要使用反斜杠/来使s h e l l忽略它的特殊含义。

假设你希望使用e c h o命令输出这样的字符串:“/ d e v / r m t 0”,那么我们只要在引号前面加上反斜杠/即可:

                                                                      $ echo "/"/dev/rmt0"/"

"/dev/rmt0"

$

read的用法,这是在"man bash"中的一段

                                                                      read [-ers] [-u fd] [-t timeout] [-a aname] [-p prompt] [-n nchars] [-d delim] [name ...]

    One  line  is  read  from  the  standard input, or from the file descriptor fd supplied as an argument to the -u option, and  the first word is assigned to the first name, the second word to the second name, and so on, with leftover words and their  intervening  separators  assigned  to the last name.  If there are fewer words read from the input stream than names, the remaining names are  assigned  empty  values.  The characters in IFS are used to split the line into words.  The backslash character (/)  may  be used  to  remove any special meaning for the next character read and for line continuation.  Options, if supplied, have the  following meanings:

    -a aname

    The words are assigned to sequential indices of the array variable aname, starting at 0.  aname is unset before any new  values  are  assigned.   Other  name  arguments  are ignored.

    -d delim

    The first character of delim is  used  to  terminate  the input line, rather than newline.

    -e     If the standard input is coming from a terminal, readline (see READLINE above) is used to obtain the line.

    -n nchars

    read returns after reading nchars characters rather  than waiting for a complete line of input.

    -p prompt

    Display prompt on standard error, without a trailing newline, before attempting to read any input.  The prompt is displayed only if input is coming from a terminal.

   -r     Backslash does not act as an escape character.  The backslash is considered to be part of the line.  In  particular,  a  backslash-newline pair may not be used as a line continuation.

   -s     Silent mode.  If input is coming from a terminal, characters are not echoed.

   -t timeout

   Cause  read  to time out and return failure if a complete line of input is not read within timeout  seconds.  This option  has  no  effect if read is not reading input from the terminal or a pipe.

    -u fd  Read input from file descriptor fd.

    If no names are supplied, the line read is assigned to the ariable  REPLY.   The  return  code  is zero, unless end-of-file is ncountered, read times out, or an invalid  file  descriptor  is supplied as the argument to -u. 经测试发现许多shell资料中没有介绍过的新内容,或许地球人都知道了^_^,不管怎样希望有兴趣的一起琢磨一下。

以下是我用来测试的代码,结果已经略去,请大家自行测试。

                                                                      read -p "how old r u? " age

echo $age

read -p "some words? " -a words

echo ${words[*]}

read -p "Password: " -s passwd                                 

echo $passwd 

read -t 5 auth

echo $auth

read -n 1 key

read -dq -p "input something end with q: " menu

read -e file #在这试试命令历史和补齐功能

其它:可以自己练习

                                                                      [[email protected] sam]$ read name

sam

[[email protected] sam]$ echo $name

sam

[[email protected] sam]$ read name surname

sam ch

[[email protected] sam]$ echo $name surname

sam surname

[[email protected] sam]$ read name surname

sam ch yiir

[[email protected] sam]$ echo $name

sam

[[email protected] sam]$ echo $surname

ch yiir

                                                                      [[email protected] sam]$ cat var_test

#!/bin/sh

#var_test

echo -e "First Name :/c"

read name

echo -e "Middle Name :/c"

read middle

echo -e "Last name :/c"

read surname var_test文件内容如上

                                                                      [[email protected] sam]$ ./var_test

First Name :wing

Middle Name :er

Last Name:chenwy 运行var_test文件

请问上面是不是把三个值赋给name,middle,surname三个变量了???

 

test:

  /home/lee#read a b c d

1 2 3 4

/home/lee#echo $a

1

/home/lee#echo $b

2

/home/lee#echo $c

3

/home/lee#echo $d

4

/home/lee#

cat:显示文件内容,创建文件,还可以用它来显示控制字符。

注意:在文件分页符处不会停下来;会一下显示完整个文件。因此,可以使用m o r e命令或把c a t命令的输出通过管道传递到另外一个具有分页功能的命令中,使用命令less file可实现相同的功能。

如下形式

                                                                      $ cat myfile | more

$ cat myfile | pg c a t命令的一般形式为:

                                                                      cat [options] filename1 ... filename2 ... 1、显示名为m y f i l e的文件:

                                                                      $ cat myfile 2、显示m y f i l e 1、m y f i l e 2、m y f i l e 3这三个文件,可以用:

                                                                      $ cat myfile1 myfile2 myfile3 3、创建一个包含上述三个文件的内容,名为b i g f i l e的文件,可以用输出重定向到新文件中:

                                                                      $ cat myfile1 myfile2 myfile3 > bigfile 4、如果cat的命令行中没有参数,输入的每一行都立刻被cat命令输出到屏幕上,输入完毕后按< C T R L - D >结束

                                                                      $ cat

Hello world 

Hello world  

<ctrl+d>

$ 5、新建文件

                                                                      $cat >myfile

This is great

<ctrl-d>

$cat myfile

This is great cat:参数选项

使用方式:

                                                                      cat [-AbeEnstTuv] [--help] [--version] fileName 说明:把档案串连接后传到基本输出(萤幕或加 > fileName 到另一个档案) 

参数:

  -n 或 --number 由 1 开始对所有输出的行数编号 

-b 或 --number-nonblank 和 -n 相似,只不过对于空白行不编号 

-s 或 --squeeze-blank 当遇到有连续两行以上的空白行,就代换为一行的空白行 

-v 或 --show-nonprinting 显示非打印字符 例:

显示时加上行号

                                                                      $cp /etc/httpd/conf/httpd /usr/sam 

$ cat -n httpd.conf 把 httpd.conf 的内容加上行号后输入 httpd1.conf 这个文件里

                                                                      $cat -n httpd.conf > httpd1.conf 对文件httpd.conf加上行号(空白不加)后显示

                                                                      $ cat -b httpd.conf 把 textfile1 和 textfile2 的档案内容加上行号(空白行不加)之后将内容附加到 textfile3 里。

                                                                      $ cat -b textfile1 textfile2 >> textfile3 清空/etc/test.txt档案内容

                                                                      $cat /dev/null > /etc/test.txt 使用 sed 与 cat 除去空白行

                                                                      $ cat -s /etc/X11/XF86Config | sed '/^[[:space:]]*$/d' -s项我试了一下,不成功,不知是不是用错了

其它参数来自:(这个我没试)

http://bbs.chinaunix.net/forum/viewtopic.php?t=438463&highlight=cat

cat 还可以在您查看包含如制表符这样的非打印字符的文件时起帮助作用。您可以用以下选项来显示制表符:

  * -T 将制表符显示为 ^I 

* -v 显示非打印字符,除了换行符和制表符,它们使用各自效果相当的“控制序列”。例如,当您处理一个在 Windows 系统中生成的文件时,这个文件将使用 Control-M(^M)来标记行的结束。对于代码大于 127 的字符,它们的前面将会被加上 M-(表示“meta”),这与其它系统中在字符前面加上 Alt- 相当。 

* -E 在每一行的结束处添加美元符($)。 显示非打印字符

                                                                      $ cat -t /etc/X11/XF86Config 

... 

# Multiple FontPath entries are allowed (they are concatenated together) 

# By default, Red Hat 6.0 and later now use a font server independent of 

# the X server to render fonts. 

^IFontPath^I"/usr/X11R6/lib/X11/fonts/TrueType" 

^IFontPath^I"unix/:7100" 

EndSection 

...

                                                                      $ cat -E /etc/X11/XF86Config 

... 

# Multiple FontPath entries are allowed (they are concatenated together)$ 

# By default, Red Hat 6.0 and later now use a font server independent of$ 

# the X server to render fonts.$ 

FontPath "/usr/X11R6/lib/X11/fonts/TrueType"$ 

FontPath "unix/:7100"$ 

EndSection$ 

...

                                                                      $ cat -v /etc/X11/XF86Config 

... 

^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@M-|M-8^X^@^@^@ 

P^@^O"M-X^O [email protected]^M^@^@^@M-^@^O"[email protected]^@M-8*^@ 

@M-^[email protected]|A([email protected])M-yM-|M-sM-*M-hW^A^@^@j^@ 

M-|M-sM-%[email protected]^@^B^@^@M-sM-+fM-^A= ^@ ^@ 

F^@^@ ^@M-9^@^H^@^@M-sM-$M-G^E([email protected]^? 

^IM-A5^@^@^D^@PM-^]M-^/X1M-H%^@^@^D^@tyM-G 

...

 

tee:读取标准输入的数据,并将其内容输出成文件。 

  语   法:tee [-ai][--help][--version][文件…] 

  补充说明:tee指令会从标准输入设备读取数据,将其内容输出到标准输出设备,同时保存成文件。我们可利用tee把管道导入的数据存成文件,甚至一次保存数份文件。 

  参   数:-a 附加到既有文件的面,而非覆盖它。如果给予tee指令的文件名称已经存在,预设会覆盖该文件的内容。加上此参数,数据会新增在该文件内容的最面,而不会删除原先之内容。 

       -i 忽略中断信号 

       --help 在线帮助 

       --version 显示版本信息 

  例一: 

  列出文本文件slayers.story的内容,同时复制3份副本,文件名称分别为ss-copy1、ss-copy2、ss-copy3: 

  

                                                                      $ cat slayers.story |tee ss-copy1 ss-copy2 ss-copy3 例一: 把列出当前目录,并把结果结到myfile里

  

                                                                      $ls -l |tee myfile 管道:可以通过管道把一个命令的输出传递给另一个命令作为输入。管道用竖杠|表示。它的一般形式为:

                                                                      命令1 |命令2

其中|是管道符号。 上例就是 

 

标准输入、输出和错误

当我们在s h e l l中执行命令的时候,每个进程都和三个打开的文件相联系,并使用文件描述符来引用这些文件。由于文件描述符不容易记忆, s h e l l同时也给出了相应的文件名。

下面就是这些文件描述符及它们通常所对应的文件名:

  文件文件描述符

输入文件—标准输入0:它是命令的输入,缺省是键盘,也可以是文件或其他命令的输出。

输出文件—标准输出1:它是命令的输出,缺省是屏幕,也可以是文件。

错误输出文件—标准错误2:这是命令错误的输出,缺省是屏幕,同样也可以是文件。 如果没有特别指定文件说明符,命令将使用缺省的文件说明符(你的屏幕,更确切地说是你的终端)。

系统中实际上有1 2个文件描述符,但是正如我们在上表中所看到的, 0、1、2是标准输入、输出和错误。可以任意使用文件描述符3到9。

在执行命令时,可以指定命令的标准输入、输出和错误,要实现这一点就需要使用文件重定向。表5 - 1列出了最常用的重定向组合,并给出了相应的文件描述符。

在对标准错误进行重定向时,必须要使用文件描述符,但是对于标准输入和输出来说,这不是必需的。

                                                                      常用文件重定向命令

command > filename 把把标准输出重定向到一个新文件中

command >> filename 把把标准输出重定向到一个文件中(追加)

command 1 > fielname 把把标准输出重定向到一个文件中

command > filename 2>&1 把把标准输出和标准错误一起重定向到一个文件中

command 2 > filename 把把标准错误重定向到一个文件中

command 2 >> filename 把把标准输出重定向到一个文件中(追加)

command >> filename 2>&1 把把标准输出和标准错误一起重定向到一个文件中(追加)

command < filename >filename2 把c o m m a n d命令以f i l e n a m e文件作为标准输入,以f i l e n a m e 2文件

作为标准输出

command < filename 把c o m m a n d命令以f i l e n a m e文件作为标准输入

command << delimiter 把从标准输入中读入,直至遇到d e l i m i t e r分界符

command <&m 把把文件描述符m作为标准输入

command >&m 把把标准输出重定向到文件描述符m中

command <&- 把关闭标准输入

exec:

e x e c命令可以用来替代当前s h e l l;换句话说,并没有启动子s h e l l。使用这一命令时任何现有环境都将会被清除,并重新启动一个s h e l l。它的一般形式为:

exec command

其中的c o m m a n d通常是一个s h e l l脚本。

我所能够想像得出的描述e x e c命令最贴切的说法就是:当这个脚本结束时,相应的会话可能就结束了。e x e c命令的一个常见用法就是在用户的. p r o f i l e最后执行时,用它来执行一些用于增强安全性的脚本。如果用户的输入无效,该

s h e l l将被关闭,然后重新回到登录提示符。e x e c还常常被用来通过文件描述符打开文件。

e x e c在对文件描述符进行操作的时候(也只有在这时),它不会覆盖你当前的s h e l l。

可以看网中人《shell十三问》第六节:

6) exec 跟 source 差在哪? 

能把十三问一次性看完最好,不过对我来说还是有些难度,今天才弄清楚第四问,看了好久才明白,目前为止,看完1,2,3,4,及11

exec:

e x e c命令可以用来替代当前s h e l l;换句话说,并没有启动子s h e l l。使用这一命令时任何现有环境都将会被清除,并重新启动一个s h e l l。它的一般形式为:

exec command

其中的c o m m a n d通常是一个s h e l l脚本。

e x e c在对文件描述符进行操作的时候,它不会覆盖你当前的s h e l l。

source和exec的区别

1,我认为他们带的参数是不一样的

source通常是shell脚本,而exec不但可以把一个脚本当成参数,而且还可以把一个系统命令当参数,例如: exec ls

2,另外一个不同就是,exec任务执行完毕后,会执行类似logout的操作,而source执行完一个任务后返回当前的shell.

3,还有,他们的用途也不是一样的

 

在输入输出概念里,内联输入重定向也是个很常用的用法,在自动FTP脚本里、SHELL的生成器里,wingger可以把它再加进来,搜集的过程就是一个非常好的学习过程!!! :P 

如:

                                                                      ftp -ni <<ENDOFSCRIPT

open 192.168.20.100

user username  pwd

bin

prom

cd /u

mput *

close

bye

ENDOFSCRIPT

  cat > mvfile.sh <</END

for i in `ls *.tar|sed -e 's//.tar//'`

do

      mkdir $i

      mv ${i}.tar $i

done

END