linux shell使用

来源:互联网 发布:淘宝买家好评率查询网 编辑:程序博客网 时间:2024/06/10 23:22

exec >/dev/null 2>&1
exec的执行结果不输出,直接丢弃>/dev/null
如果有错误,错误信息输出到标准输出中
如果全部都要重定向的话每一条命令后面>>并不方便,可以这么做。
在开头就声明

  1. exec 1>>$log_file
复制代码
表示将脚本中所有的正确输出全部追加到$log_file,错误信息会输出到stdout。

如果想把错误信息也输出到$log_file,那么只需要补一句
  1. exec 2 >> $log_file
复制代码
就可以了

exec和source都属于bash内部命令(builtins commands),在bash下输入man exec或man source可以查看所有的内部命令信息。

bash shell的命令分为两类:外部命令和内部命令。外部命令是通过系统调用或独立的程序实现的,如sed、awk等等。内部命令是由特殊的文件格式(.def)所实现,如cd、history、exec等等。

在说明exe和source的区别之前,先说明一下fork的概念。

    fork是linux的系统调用,用来创建子进程(child process)。子进程是父进程(parent process)的一个副本,从父进程那里获得一定的资源分配以及继承父进程的环境。子进程与父进程唯一不同的地方在于pid(process id)。

    环境变量(传给子进程的变量,遗传性是本地变量和环境变量的根本区别)只能单向从父进程传给子进程。不管子进程的环境变量如何变化,都不会影响父进程的环境变量。

 

shell script:

有两种方法执行shell scripts,一种是新产生一个shell,然后执行相应的shell scripts;一种是在当前shell下执行,不再启用其他shell。

新产生一个shell然后再执行scripts的方法是在scripts文件开头加入以下语句

#!/bin/sh

一般的script文件(.sh)即是这种用法。这种方法先启用新的sub-shell(新的子进程),然后在其下执行命令。

另外一种方法就是上面说过的source命令,不再产生新的shell,而在当前shell下执行一切命令。

 

source:

source命令即点(.)命令。

在bash下输入man source,找到source命令解释处,可以看到解释”Read and execute commands from filename in the current shell environment and …”。从中可以知道,source命令是在当前进程中执行参数文件中的各个命令,而不是另起子进程(或sub-shell)。

 

exec:

在bash下输入man exec,找到exec命令解释处,可以看到有”No new process is created.”这样的解释,这就是说exec命令不产生新的子进程。那么exec与source的区别是什么呢?

exec命令在执行时会把当前的shell process关闭,然后换到后面的命令继续执行。

Linuxexec的用法总结

先总结一个表:

exec命令

作用

exec ls

shell中执行lsls结束后不返回原来的shell中了

exec <file< span="" style="word-wrap: break-word;">

file中的内容作为exec的标准输入

exec >file

file中的内容作为标准写出

exec 3<file< span="" style="word-wrap: break-word;">

file读入到fd3

sort <&3

fd3中读入的内容被分类

exec 4>file

将写入fd4中的内容写入file

ls >&4

Ls将不会有显示,直接写入fd4中了,即上面的file

exec 5<&4

创建fd4的拷贝fd5

exec 3<&-

关闭fd3

1. exec 执行程序

 虽然execsource都是在父进程中直接执行,但exec这个与source有很大的区别,source是执行shell脚本,而且执行后会返回以前的shell。而exec的执行不会返回以前的shell了,而是直接把以前登陆shell作为一个程序看待,在其上经行复制。

举例说明:

root@localhost:~/test#exec ls

exp1  exp5  linux-2.6.27.54  ngis_post.sh  test  xen-3.0.1-install

root@localhost:~/test#exec >text

root@localhost:~/test#ls

root@localhost:~/test#pwd

root@localhost:~/test#echo "hello"

root@localhost:~/test#exec>/dev/tty

root@localhost:~/test#cat text 

exp1

exp5

linux-2.6.27.54

ngis_post.sh

test

text

xen-3.0.1-install

/root/test

hello

root@localhost:~/test#

Exec >text 是将当前shell的标准输出都打开到text文件中

root@localhost:~/test#cat test

ls

Pwd

root@localhost:~/test#bash

root@localhost:~/test#exec <test< span="" style="word-wrap: break-word;">

root@localhost:~/test#ls

exp1  exp5  linux-2.6.27.54  ngis_post.sh  test  text  xen-3.0.1-install

root@localhost:~/test#pwd

/root/test

root@localhost:~/test#

root@localhost:~/test#exit       #自动执行

2. exec的重定向

  先上我们进如/dev/fd/目录下看一下:

root@localhost:~/test#cd /dev/fd

root@localhost:/dev/fd#ls

0  1  2  255

默认会有这四个项:0是标准输入,默认是键盘。

1是标准输出,默认是屏幕/dev/tty

2是标准错误,默认也是屏幕

255

当我们执行exec 3>test时:

root@localhost:/dev/fd#exec 3>/root/test/test 

root@localhost:/dev/fd#ls

0  1  2  255  3

root@localhost:/dev/fd#

看到了吧,多了个3,也就是又增加了一个设备,这里也可以体会下linux设备即文件的理念。这时候fd3就相当于一个管道了,重定向到fd3中的文件会被写在test中。关闭这个重定向可以用exec 3>&-

root@localhost:/dev/fd#who >&3

root@localhost:/dev/fd#ls >&3

root@localhost:/dev/fd#exec 3>&-

root@localhost:/dev/fd#cat /root/test/te

test  text  

root@localhost:/dev/fd#cat /root/test/test 

root     tty1         2010-11-16 01:13

root     pts/0        2010-11-15 22:01 (192.168.0.1)

root     pts/2        2010-11-16 01:02 (192.168.0.1)

0

1

2

255

3

3. 应用举例:

        exec 3<test< span="" style="word-wrap: break-word;">

        while read -u 3 pkg

do

echo "$pkg"

done


vim中显示windows或者dos的换行符^M

http://blog.chinaunix.net/uid-14214482-id-3220695.html

 

linux下,如果需要在vim中查看^M,需要使用如下命令:e ++ff=unix %

 

有时候,我们在 Linux中打开曾在 Win中编辑过的文件时,会在行尾看到 ^M字符。虽然,这并不影响什么,但心里面还是有点不痛快。如果想要删除这些 ^M 字符,可以使用 Vim来轻松搞定它。

Vim的命令模式中输入 :%s/^M$//g后,回车即会自动删除该文件中的所有 ^M字符。

^M注意要用 Ctrl + V Ctrl + M来输入

Linuxwindows下回车换行格式转换回车换行结尾转换  

http://rocolex.blog.163.com/blog/static/6844641020115241629669/

 

一、windows的文件到linux下的转换方法:

1.sed命令替换

sed -e 's/^M//g' original.txt > target.txt(注意^MLinux/Unix下是这样输入的:先按CTRL+v,接着按CTRL+SHIFT+m,呵呵~~其实俺主要就是为了记录一下这个输入方法)

2.vi中替换

:%s/^M//g
3.sed
命令替换
sed -e 's/.$//' dos.txt > linux.txt

二、Linux文本传到windows系统,转换方法:
sed -e 's/$/\r/' 1pnet.txt >dos.txt

 

 

while read的关于读取最后一行的问题

 

http://bbs.csdn.net/topics/390108418

 

windows使用\r\n作为行结尾,而unix使用\n作为行结尾

使用notepad编辑的文件,如果最后一行没有回车,采用二进制方式上传到unix后,因为最后一行没有\n,会被认为是不完整的文件

循环读到最后一行后,认为达到文件结尾,那个read SERVER会返回假,循环结束。


1
、最好使用dos2unix命令转换为unix格式
2
、实在不行,只能在while循环之后,再添加一个额外处理

while read line读取文件时,如果文件最后一行之后没有换行符\n,则read读取最后一行时遇到文件结束符EOF,循环终止,虽然此时$line内存有最后一行,但程序已经没有机会再处理此行,因此可以通过以下代码来解决此问题:

while read line || [[ -n ${line} ]]; do...done

这样当文件没有结束时不会测试-n $line,当遇到文件结束时,仍然可以通过测试$line是否有内容来进行继续处理。


 

[shell] while read line最后一行读不出  

http://wangjunle23.blog.163.com/blog/static/11783817120135254317901/

 

如果存在一个文本${file},使用while read line去读取时发现,最后一行无法读出:

 

       while read line
        do
            echo"$line 1 n"
        done< ${file}

 

如何解决这种情况呢,可以考虑以下的方法:

    DONE=false
    until $DONE 

   do read|| DONE=true
        echo "$REPLY 1 n"
    done< ${files}

 



awk '$1~/#/{print}' group_file1  



$ zcat  1.txt.gz | less


<system>


shell是直接读取gz中的内容还是读取解压缩后的文本内容?


我想写个脚本,读取文本中的某几行数据,然后输出成新文件: 比如: abc001230001.xml abc001230002.xml abc001230003.xml ... abc001230100.xml 我想将它们每个文件中的第1~10行以及50~60行的数据读取,并输出一个新文件(每个文件都输出一个新... 展开
lingfeng0928 | 浏览 2273 次
发布于2015-06-09 10:53 最佳答案
# for file in `ls abc*.xml`;do sed -n -e '1,10p' -e '50,60p' $file > ${file}_new;done






编写一个shell脚本 解压a目录下所有gz文件到b目录


cd a;find . -name "*.gz" -exec tar xvf {} -C b/ \;


 今天工作中遇到一个类似下面提到的需求,这是我写的第一个脚本程序,比较丑陋,还是记录下,以备后用。


需求:某个目录下每天生成一个文件,生成时将文件压缩成.gz格式,如今天是2013年6月3号,则生成file-20130603-log.gz文件,而另一个程序则是读取file-20130603-log文件,且程序中读文件时当文件名包括"file"时则读取。


实现:写一个脚本将src目录下当前日期的.gz文件先解压,并将解压后的文件移到另一个目录des下,这样程序读取时就读取des目录下的文件。shell脚本如下:




#!/bin/bash


date=`date +%Y%m%d`   #生成当前日期格式为,若想得到昨天的日期date=`date -d yesterday +%Y%m%d`


srcFile=/home/daen/src/  #src文件即.gz格式文件所在目录


desPath=/home/daen/des/ #解压后移送到的des目录


suffix=.gz #文件后缀


desFile=tx3.login.$date.log #解析程序读取的文件名即解压后的文件名


file=$srcFile$desFile$suffix #被解压文件的完整路径


if [ -f $file ];then


   gunzip -c $file > $desPath$desFile #解压文件并将文件定义到des目录下


else


   echo $file 'not exist!'


fi




///////////////////////////////////


将文件压缩成.gz格式文件的命令:


gzip -c 源文件 > 目标文件


如将test.txt文件压缩成test.gz文件


gzip -c test.txt > test.gz






#!/bin/sh  
  
ls *.tar.gz > list.txt  
  
for TAR in `cat list.txt`  
do  
        tar zxf $TAR  
done  
  
rm -rf list.txt  


目录下的文本,并写到txt中,之后循环txt


#!/bin/bash
ls  *.txt > list
for txtdir in `cat list`
do
  
    for line in `cat $txtdir`
             do echo $line | temp.txt
              done
done


#!/bin/bash
ls  *.txt > list
i=0
for txtdir in `cat list`
do


    for line in `cat $txtdir`
             do
               if [ $i == 0 ]
                  then
                   echo $line > temp.txt
                      ((i++))
                     else
                   echo $line >> temp.txt
                    fi
              done
done




Linux Shell中写循环时,常常要用到变量的自增,现在总结一下整型变量自增的方法。
 我所知道的,bash中,目前有五种方法:
1. i=`expr $i + 1`;
 2. let i+=1;
 3. ((i++));
 4. i=$[$i+1];
 5. i=$(( $i + 1 ))
可以实践一下,简单的实例如下:




#!/bin/bash
 i=0;
 while [ $i -lt 4 ];
 do
    echo $i;
    i=`expr $i + 1`;
    # let i+=1;
    # ((i++));
    # i=$[$i+1];
    # i=$(( $i + 1 ))
done 




另外,对于固定次数的循环,可以通过seq命令来实现,就不需要变量的自增了;实例如下:


#!/bin/bash
 for j in $(seq 1 5)
 do
   echo $j
 done 




 
 首先, Shell赋值时,等号左右两边是不能有空格的


一般赋值 
s=123  
echo $s




日期赋值 
s=`date +"%Y-%m-%d"` # 注意`不是单引号, 而是~下面的点  
echo %s`




对字符串进行连接
str1=abc
str3=${str1}.gz 
echo $str3




Shell 命令中的日期的相关参数
%%


a literal %
%a


locale's abbreviated weekday name (e.g., Sun)
%A
locale's full weekday name (e.g., Sunday)
%b


locale's abbreviated month name (e.g., Jan)
%B


locale's full month name (e.g., January)
%c


locale's date and time (e.g., Thu Mar 3 23:05:25 2005)
%C


century; like %Y, except omit last two digits (e.g., 21)
%d


day of month (e.g, 01)
%D




shell读取一行数据后写到另一文件为什么不是一行记录了
因为in操作符以任意空白字符作为分割, 而read line是以回车符作为分割。






版权声明:本文为博主原创文章,未经博主允许不得转载。




1 #!/bin/sh
 cat FILENAME  |while  read LINE
 do
     echo  "$LINE"
 done
 exit  0  


 


一次读取一行,但是最前面的空格会被忽略。  


 


2   #!/bin/sh
 for  LINE in  ` cat FILENAME `
 do
     echo  $LINE
 done
 exit  0  


 


这个并不一定是一次读取一行,而是按照空格为分隔符。  


 


3   !/bin/sh
 while  read LINE
 do
       echo  $LINE   
 done  <  FILENAME  


和1一样。


接触linux操作系统之后使用vi/vim编辑器用的就比较多,其实vi/vim编辑文件特别方便,但是一些常见的指令模式下的命令确很容易忘,特别是复制剪切粘贴经常忘,所以小结下以后查用起来比较方便。

1.复制剪切粘贴撤销
复制:
复制一行则:yy
复制三行则:3yy,即从当前光标+下两行。
复制当前光标所在的位置到行尾:y$
复制当前光标所在的位置到行首:y^

剪切:
剪切一行:dd
前切三行:3dd,即从当前行+下两行被剪切了。
剪切当前行光标所在的位置到行尾:d$
剪切当前行光标所在的位置到行首:d^

粘贴:
用v选中文本之后可以按y进行复制,如果按d就表示剪切,之后按p进行粘贴。

撤销与恢复:
'u' : 撤销上一个编辑操作
'ctrl + r' : 恢复,即回退前一个命令
'U' : 行撤销,撤销所有在前一个编辑行上的操作

2.屏幕翻页
Ctrl+u: 向上翻半屏
Ctrl+f: 向上翻一屏
Ctrl+d: 向下翻半屏
Ctrl+b: 向下翻一屏

3.移动光标指令
移动光标普遍使用的是方向键,考虑兼容问题,vi定义太多的方向指令,下面只是一小小部分(常用的几个):
space: 光标右移一个字符
Backspace: 光标左移一个字符
Enter: 光标下移一行
nG: 光标移至第n行首
n+: 光标下移n行
n-: 光标上移n行
n : 光标移至当前行尾

4.插入删除指令
常用插入、删除指令如下:
i:在当前光标前插入,光标后文本向后移
a:从当前光标后插入,光标后文本后移
I:在光标所在行首插入(第一个非空白字符前)
A:从光标所在行末插入
o: 在光标所在行下面新增一行(并进入输入模式)
O: 在光标所在行上方新增一行(并进入输入模式)
x: 删除光标所在字符,等同于[Delete]功能键
X: 删除光标前字符,相当与[Backspace]
dd: 删除光标所在的行
r: 修改光标所在字符
R: 替换当前字符及其后的字符,直到按 [ESC]
s: 从当前光标位置处开始,以输入的文本替代指定数目的字符
S: 删除指定数目的行,并以所输入文本代替之
do: 删至行首
d$: 删至行尾

5.退出
退出输入模式,先按一下[ESC]键(有时要多按两下),然后执行:
:w!
:w ——保存当前文件
:wq —— 存盘退出(与指令 :x 功能相同)
:q —— 直接退出,如已修改会提示是否保存
:q! ——不保存直接退出 


0 0
原创粉丝点击