bash2----基本1

这个随笔主要讲一些关于bash的小track

1、如何注释多行bash:

:<<'

注释内容

'

:<<WORD

注释内容

WORD

:<<'BLOCK

注释内容

'BLOCK

1.1这个是补充的一个知识点:

命令替换用的点是```,在左上角 ESC下面那个,而不是单引号''''''''这个东西,但是注释内容用的是单引号

所以,basename是print NAME with any leading directory components removed的命令,他既可以自己把名字输出于终端,也可以通过echo进行命令替换,但是命令替换一定要用``  而不是''

whois 是关于域名查找的命令,需要由apt-get下载安装。

2、let 是bash里面特有的,所以#!/bin/bash且调试用bash scripitionname.sh才可以使用let。否则会出错

  echo -n "内容" .每一个echo末尾会接一个换行符,如果有了-n则去掉换行符,常用于循环echo

  read 变量 相当于C语言中的scanf从终端读入变量

  输出=${变量\变量中关键词\替换词}#把变量中的关键词替换成替换词输出到输出中${\\}

3、学习两个命令sed和seq

  sed – Stream editor for filtering and transforming text用于筛选和转换文本留的编辑器

  eg: echo front | sed 's/front/back/' #这会输出back。

  这个地方也是用了替换的命令 这个替换命令由字母 s 来代表,其后跟着查找 和替代字符串,斜杠字符做为分隔符。分隔符的选择是随意的。按照惯例,经常使用斜杠字符, 但是 sed 将会接受紧随命令之后的任意字符做为分隔符。我们可以按照这种方式来执行相同的命令:

   echo front | sed 's_front_back_'

   sed 中的大多数命令之前都会带有一个地址,其指定了输入流中要被编辑的文本行。如果省略了地址, 然后会对输入流的每一行执行编辑命令。最简单的地址形式是一个行号。我们能够添加一个地址 到我们例子中:

  eg: echo -e 'front\n111' | sed '2s/111/back/'

    front

    back  

-e是处理特殊字符,不会把\n  \b \t当做一般 字符输出这里\n就是换行,  而 2s就是把第二行的111换成back。特别的$s是最后一行

    sed -n '2,5p' distros.txt   #输出distros.txt的第2-5行

  具体而言:

  我们用了-n和p

选项与参数:
-n :使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN 的数据一般都会被列出到终端上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。
-e :直接在命令列模式上进行 sed 的动作编辑;
-f :直接将 sed 的动作写在一个文件内, -f filename 则可以运行 filename 内的 sed 动作;
-r :sed 的动作支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法)
-i :直接修改读取的文件内容,而不是输出到终端。
function:
a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
d :删除,因为是删除啊,所以 d 后面通常不接任何咚咚;
i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
p :列印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~
s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!

   cat file | tr [a-z] [A-Z] > new_file    #tr的基本用法,另外可以[0-9] [a-j]

   cat file | tr -d "ABC" > new_file    #删除file中的ABC字符,A,B,C字母都会被删除!!!不是删除出现的"ABC"字符串

   cat file | tr -d '\n' > new_file

4、位置参数

  从命令行传递到脚本的参数:$0 $1 $2....

$0表示脚本名字本身,$1是第一个参数,$9之后需要用大括号括起来了${10}

另外两个比较特殊的变量$*和$@表示所有的位置参数

 
5、\的行为依赖于它自身是否被转义, 被引用(""), 或者是否出现在命令替换here,document中. 

 # 命令替换
 echo `echo \z` # z
 echo `echo \\z` # z
 echo `echo \\\z` # \z
 echo `echo \\\\z` # \z
 echo `echo \\\\\\z` # \z
 echo `echo \\\\\\\z` # \\z
 echo `echo "\z"` # \z
 echo `echo "\\z"` # \z

 # Here document
 cat <<EOF
 \z
 EOF # \z
 cat <<EOF
 \\z
 EOF # \z

  

例子 5-1. echo出一些诡异变量

 #!/bin/bash
 # weirdvars.sh: echo出一些诡异变量.

 var="'(]\\{}\$\""
 echo $var # '(]\{}$"
 echo "$var" # '(]\{}$" 和上一句没什么区别.Doesn't make a difference.

 echo

 IFS='\'
 echo $var # '(] {}$" \ 字符被空白符替换了, 为什么?
 echo "$var" # '(]\{}$"

 # 这个例子由Stephane Chazelas提供.

 exit 0

首先,我们需要知道双引号的作用,他是用于阻止单词分割(word splitting)或者用于保留空白

例如:

 variable1="a variable containing five words"
 COMMAND This is $variable1 # 用下面7个参数执行COMMAND命令:
 # "This" "is" "a" "variable" "containing" "five" "words"

 COMMAND "This is $variable1" # 用下面1个参数执行COMMAND命令:
 # "This is a variable containing five words"


 variable2="" # Empty.

 COMMAND $variable2 $variable2 $variable2 # COMMAND将不带参数执行.
 COMMAND "$variable2" "$variable2" "$variable2" # COMMAND将以3个空参数来执行.
 COMMAND "$variable2 $variable2 $variable2" # COMMAND将以1个参数来执行(2空格).

具体以echo为例子:

#!/bin/bash
var="a b     c d"
echo $var.tar   fas            ???    #a b c d.tar fas tmp
echo "$var.tar   fas            ???" #a b    c d.tar   fas            ???
echo "$var1.tar   fas            ???"#.tar   fas            ???
echo "$var.tar" "$var" "$var1" "var"#a b   c d.tar a b   c d var
echo $var $var $var1 var            #a b c d a b c d var

这个例子告诉我们:

  1、单词分割不能阻止COMMAND对于变量.tar的识别,但是如果变量1,那么COMMAND将无法识别,即$var.tar可以识别,$var1不能识别为a b    c d1

  2、因为单词分割 所以第一个echo 后面不管有几个空格,最终输出只有一个,尽管var是由“”赋值的变量,这些空格也不在保留

  3、如果想存在多个空格,在echo中,如第二个echo,应该加双引号

  4、最后一个和第一个情况一样 只保留一个空格输出。

我也不知道为什么第一个echo后面是一个 tmp,知道的朋友希望可以给我留言 谢谢!

例二:#!/bin/bash

var="a b     c d"
echo $var.tar   fas            "$var"    #a b c d.tar fas a b  c d
echo $var.tar fas       "$var" |od -t d1  #od -t o1 OR od -c
echo "$var.tar fas ???" #a b c d.tar fas a b  c d echo "$var1.tar fas ???"#.tar fas ??? echo "$var.tar" "$var" "$var1" "var"#a b c d.tar a b c d var echo $var $var $var1 var #a b c d a b c d var

我们使用od命令,什么是od命令?

名称:od
作用:格式化输出文件中的数据
提要:
         od [OPTION]... [FILE]...
         od [-abcdfilosx]... [FILE] [[+]OFFSET[.][b]]
     od --traditional [OPTION]... [FILE] [[+]OFFSET[.][b] [+][LABEL][.][b]]
说明:
常见的文件为文本文件和二进制文件。此命令主要用来查看保存在二进制文件中的值。比如,程序可能输出大量的数据记录,每个数据是一个单精度浮点数。这些数据记录存放在一个文件中,如果想查看下这个数据,这时候od命令就派上用场了。在我看来,od命令主要用来格式化输出文件数据,即对文件中的数据进行无二义性的解释。不管是IEEE754格式的浮点数还是ASCII码,od命令都能按照需求输出他们的值。
如果没有指定文件名,或者文件名为“-”,则从标准输入读入数据。

-a:等价于 -t a.表示ASCII码的名字
-b:等价于-t o1,选择单字节,并且按照3个数值位的八进制数进行解释,(-t otcal+1字节大小od -b <-->od -t o1)
-c:等价于-t c,选择ASCII码字符或者是转义字符
-d:等价于-t u2:选择无符号2字节单位
-f:等价于-t fF,选择单精度浮点数
-i:等价于-t dI,选择十进制整型
-l:等价于-t dL,选择十进制长整型
-o:等价于-t o2,选择两个字节的单元并按照八进制进行解释
-s:等价于-t d2,选择两字节单元并按照十进制解释(选一字节单元并按照十进制解释:d1)
-x:等价于-t x2,选择两个字节单元,并作十六进制解释

输出结果为:

(注:040是空格,141是a,056是 . , 011是水平制表符(tab),012是\n)

a b c d.tar fas a b   c d

0000000 141 040 142 040 143 040 144 056 164 141 162 040 146 141 163 040

0000020 141 040 142 040 143 040 144 012

a b     c d.tar fas      a b     c d

0000000 141 040 142 040 040 040 040 040 143 040 144 056 164 141 162 040

0000020  040 146 141 163 040 011 011 011 011 141 040 142 040 040 040 040

0000040 143 040 144 012

0000044

........

这一段二进制码告诉我们:

1、没有由双引号引入的echo 对应的tab ,空格(统称为IFS),最终只有一个空格(040)表示。

2、使用了双引号,不管是echo中间引用还是全都引用, 在引用的部分都按照输入来输出,而不会把一个或多个 tab或空格变成1个。

IFS:

  Shell 脚本中有个变量叫 IFS(Internal Field Seprator) ,内部域分隔符。完整定义是The shell uses the value stored in IFS, which is the space, tab, and newline characters by default, to delimit words for the read and set commands, when parsing output from command substitution, and when performing variable substitution.

     Shell 的环境变量分为 set, env 两种,其中 set 变量可以通过 export 工具导入到 env 变量中。其中,set 是显示设置shell变量,仅在本 shell 中有效;env 是显示设置用户环境变量 ,仅在当前会话中有效。换句话说,set 变量里包含了 env 变量,但 set 变量不一定都是 env 变量。这两种变量不同之处在于变量的作用域不同。显然,env 变量的作用域要大些,它可以在 subshell 中使用。

     而 IFS 是一种 set 变量,当 shell 处理"命令替换"和"参数替换"时,shell 根据 IFS 的值,默认是 space, tab, newline 来拆解读入的变量,然后对特殊字符进行处理,最后重新组合赋值给该变量。

  更多内容引用于博文

具体而言,执行命令行为:

echo "$IFS" |od -t o1

000000 040 011 012 012

000004

echo $IFS |od -t o1

000000 012

000001

对于多个内部域分隔符,如果前后都有其他非分隔符,则没有引号的情况下由一个040(空格)表示,代表一个IFS。如果前后什么都没有则此处无任何二进制码echo。

对于有引号的情况,则按他本身的二进制码输出。

综上所述:回到例题5-1

 #!/bin/bash
 # weirdvars.sh: echo出一些诡异变量.

 var="'(]\\{}\$\""
 echo $var # '(]\{}$"
 echo "$var" # '(]\{}$" 和上一句没什么区别.Doesn't make a difference.

 echo

 IFS='\'
 echo $var # '(] {}$" \ 字符被空白符替换了, 为什么?
 echo "$var" # '(]\{}$"

 # 这个例子由Stephane Chazelas提供.

 exit 0

第三个echo 因为没有引号,则\\代表两个IFS最终由一个040输出。
第四个echo 因为有引号,则\代表转义字符,转义了\。则040变成了\(134)表示

验证代码:
 #!/bin/bash
 # weirdvars.sh: echo出一些诡异变量.

 var="'(]\\{}\$\""
 echo $var # '(]\{}$"
 echo "$var" # '(]\{}$" 和上一句没什么区别.Doesn't make a difference.

 echo

 IFS='\'
 echo $var # '(] {}$" \ 字符被空白符替换了, 为什么?
echo $var |od -t o1
echo "$var" # '(]\{}$" echo "$var"|od -t o1
# 这个例子由Stephane Chazelas提供. exit 0


猜你喜欢

转载自www.cnblogs.com/SsoZhNO-1/p/9224849.html
今日推荐