记录学习笔记、分享资源工具、交流技术思想、提升工作效率

shell 奇技淫巧

运维 xiaomudk 6年前 (2015-06-06) 6502次浏览 0个评论
文章目录[隐藏]

1.变量两边加双引号,保证原内容的格式

如果变量两边不加双引号的话,所有的多个空格被一个空格代替,所有的换行被删除
举例:

# a=`ls -l`
# echo $a
total 824 -rw-r--r-- 1 root root 878 Oct 10 18:10 1.txt -rw-r--r-- 1 root root 33083 Sep 22 16:41 a -rw-r--r-- 1 root root 29309 Sep 24 16:03 b -rw-r--r-- 1 root root 581 Oct 10 17:29 check_lockbox_timeout.sh -rwxr-xr-x 1 root root 721 Sep 24 15:55 check.sh -rw-r--r-- 1 root root 42439 Sep 22 16:32 hostgroup_name.txt -rw-r--r-- 1 root root 49948 Sep 22 16:32 host_name.txt -rw-r--r-- 1 root root 43051 Sep 24 15:55 host.txt -rw-r--r-- 1 root root 15 Oct 11 11:41 ip_list.txt -rw-r--r-- 1 root root 0 Oct 10 17:27 lockbox.log -rw-r--r-- 1 root root 289489 Sep 22 10:51 services.cfg -rw-r--r-- 1 root root 248472 Sep 24 15:55 services.cfg_1 -rw-r--r-- 1 root root 63405 Sep 24 15:55 services.cfg_2 drwxr-xr-x 2 root root 4096 Oct 11 11:06 StrictHostKeyChecking=no -rw-r--r-- 1 root root 117 Oct 14 15:59 test.sh
# echo "$a"
total 824
-rw-r--r-- 1 root root    878 Oct 10 18:10 1.txt
-rw-r--r-- 1 root root  33083 Sep 22 16:41 a
-rw-r--r-- 1 root root  29309 Sep 24 16:03 b
-rw-r--r-- 1 root root    581 Oct 10 17:29 check_lockbox_timeout.sh
-rwxr-xr-x 1 root root    721 Sep 24 15:55 check.sh
-rw-r--r-- 1 root root  42439 Sep 22 16:32 hostgroup_name.txt
-rw-r--r-- 1 root root  49948 Sep 22 16:32 host_name.txt
-rw-r--r-- 1 root root  43051 Sep 24 15:55 host.txt
-rw-r--r-- 1 root root     15 Oct 11 11:41 ip_list.txt
-rw-r--r-- 1 root root      0 Oct 10 17:27 lockbox.log
-rw-r--r-- 1 root root 289489 Sep 22 10:51 services.cfg
-rw-r--r-- 1 root root 248472 Sep 24 15:55 services.cfg_1
-rw-r--r-- 1 root root  63405 Sep 24 15:55 services.cfg_2
drwxr-xr-x 2 root root   4096 Oct 11 11:06 StrictHostKeyChecking=no
-rw-r--r-- 1 root root    117 Oct 14 15:59 test.sh

可以看出echo $a输入的时候,每个文件和目录都粘连在一起了(空格分隔),格式乱掉了。

2.复制隐藏文件

把/root/下的文件复制到/mnt/root到

cp -a /root/. /mnt/root    #就是把*换成.就可以了

3.while中使用ssh就循环一次结束的问题

文本每一行包含一个IP在while循环中使用ssh,但ssh完第一行后就退出了,

while read line 
do 
    ssh $line ls
done < ip.txt

但是使用for的时候就不存在这个问题,

原因: while中使用重定向机制,文件中的信息都已经读入并重定向给了整个while语句,所以当我们在while循环中再一次调用read语句,就会读取到下一条记录。问题就出在这里,ssh语句正好回读取输入中的所有东西(也就是把剩余文本里的东西都读进去了). 当read第二次循环的时候。文件文件已经结束了。while退出。

使用下面这个Shell可以证明这个问题:

while read line 
do 
ssh $line cat 
done < ip.txt

解决办法:

  1. 使用ssh -n "command"
  2. ssh "cmd" < /dev/null # 将ssh 的输入重定向输入。

4.find xargs结合cp或者mv的使用方法

find 出来的文件要cp或者mv 的话,可以使用find 的exec

find /tmp -name "*.txt" -exec cp {} /data/ \;

find结合xargs使用的时候,cp 或者mv文件的方法如下:

find /tmp -name "*.txt" | xargs -I {} cp {} /data/   或者
find /tmp -name "*.txt" | xargs -i cp {} /data/           

-i 表示 find 传递给xargs的结果 由{}来代替
-I 必须指定替换字符. xarg的man页中表示废弃-i参数。建议使用-I{}来代替

find xargs 结合cp 或mv 的时候,另外一种方法

find /tmp -name "*.txt" | xargs cp -t /data/
find /tmp -name "*.txt" | xargs mv -t /data/

cp和mv 的 -t 参数是指定目标目录。此时目标目录在前,源文件在后\

5.bash shell中获取字符串的长度

  • 使用wc:
    wc -L可以获取到当前行的长度,因此对于单独行的字符串可以用这个简单的方法获取,另外wc -l则是获取当前字符串内容的行数。

    # echo "abc" |wc -L
  • 使用expr
    使用expr length可以获取string的长度

    # expr length "abc"
  • 使用awk

通过awk+length的方式获取字符串长度

# echo “abc”|awk '{print length($0)}'
  • 使用 echo \${#string} 的方式
    注意:这里的string是该字符串的变量名

    name="abc"
    echo ${#name}

6.获取字符串的开头或最后的一个字符

  • 变量截取
# a=3234j35ja
# echo ${a::1}      # 获取开头的第一个字符   
3
# echo ${a: -1}      #获取最后的一个字符,注意-1前面有个空格, 但是 echo ${a: -100} ,如果越界的话,就获取到空字符。这一点需要注意,
a
  • 使用cut
# a=3234j35ja
# echo $a | cut -c 1        #获取开头的第一个字符
3
# echo $a | cut -c $((${#a}))  #获取最后的一个字符
a
  • 使用sed
# a=3234j35ja
# echo "$a" | sed -e "s/^\(.\).*$/\1/"   #获取开头的一个字符
3
# echo "$a" | sed -e "s/^.*\(.\)$/\1/"   #获取最后的一个字符
a
  • 使用awk
# a=3234j35ja
# echo "$a" | awk '{print substr($0,1,1)}'   #获取开头的一个字符 ,substr(str,start,length)
3
# echo "$a" | awk '{print substr($0,length($0))}'   #获取最后的一个字符, substr(str,start) 
a
  • 使用tail或head
# a=3234j35ja 
# echo "$a" | head -c 1        #获取开头的一个字符
3
# echo $a | tail -c 2           # 获取结尾的一个字符,tail -c 1   是结束符
a

7.删除字符串开头或结尾的一个字符

  • 字符串截取
# a=3234j35ja
# echo ${a%?}      #删除结尾的一个字符
3234j35j
# echo ${a#?}     #删除开头的一个字符
234j35ja
  • 使用cut
# a=3234j35ja
# echo $a | cut -c 2-           #删除开头的第一个字符
234j35ja
# echo $a | cut -c 1-$((${#a} -1))   #删除最后的一个字符
3234j35j
  • 使用sed
# a=3234j35ja
# echo "$a" | sed -e "s/^.//"        #删除开头的第一个字符
234j35ja
# echo "$a" | sed -e "s/.$//"        #删除最后的一个字符
3234j35j
  • 使用awk
# a=3234j35ja
# echo "$a" | awk '{print substr($0,2)}'        #删除开头的第一个字符
234j35ja
# echo "$a" | awk '{print substr($0,1,length($0)-1)}'        #删除最后的一个字符
3234j35j
  • 使用tail或head
# a=3234j35ja 
# echo "$a" | tail -c +2             #删除开头的第一个字符 ,+2表示从第2个字符开始显示
234j35ja
# echo "$a" | head -c -2               #删除最后的一个字符, -2表示显示到倒数第2个字符
3234j35j

8.shell函数返回一个字符串

function test() {
        return "${1} abc"
}

out=test "${1}"
echo "....${out}"

直接return是会报错的, return只能返回一个数字,来表示命令是否执行成功。

解决办法:

function test() {
        echo "${1} abc"
}

out=$(test "${1}")             #把test函数的标准输出,赋值给变量out
echo "....${out}"

执行结果

# sh 1.sh 11111
....11111 abc

9.修改纳秒级的文件时间

之前用touch命令修改文件时间,只是精确到秒,有些特殊情况还是需要把文件时间修改的更精确一点

  • 设置文件的访问时间和修改时间
# touch -d "2015-5-19 01:12:40.111000000" 1.txt  
# stat 1.txt 
  File: `1.txt'
  Size: 7               Blocks: 8          IO Block: 4096   regular file
Device: 803h/2051d      Inode: 2228580     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2015-05-19 01:12:40.111000000 +0800
Modify: 2015-05-19 01:12:40.111000000 +0800
Change: 2015-5-19 14:50:08.035977483 +0800

  • 设置文件的修改时间
# touch -m -d "2015-5-19 01:12:40.111000000" 1.txt  
# stat 1.txt 
  File: `1.txt'
  Size: 7               Blocks: 8          IO Block: 4096   regular file
Device: 803h/2051d      Inode: 2228580     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2015-05-19 01:12:40.111000000 +0800
Modify: 2015-5-19 12:12:12.110000000 +0800
Change: 2015-5-19 14:50:08.035977483 +0800

把-m 改成-a 就是设置文件的访问时间了


本网站采用知识共享署名-相同方式共享 4.0 国际许可协议进行授权
转载请注明原文链接:shell 奇技淫巧
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址