day13 脚本编辑-后面shell十三问太烧脑了

2022-05-22  本文已影响0人  meraner

一、理解“变量”

给一个字符串进行赋值,比如:rweldwdd='bio',意思就是这一串字符就是bio。rweldwdd就是一个变量名啦。

echo $rweldwdd就会显示出bio来。
那么把上面这些写入脚本并运行: (注意vim操作,按i键,进行编辑,按esc退出编辑,敲入:wq,保存并退出。

vim tem.sh
rweldwdd='bio'
echo $rweldwdd
bash tem.sh

则会运行sh里面的命令,显示bio字样。这真是一个最简单的脚本啊。

二、参数

在运行程序bash tam.sh p1的时候会出现什么?那就看看tem.sh里面有什么参数了。比如0,1都可以看作参数。

vim tem.sh
echo $1
bash tem.sh p1 p2

则会打印出第一个数据p1

如果想打印出第10个以后的数据就要用下面的格式

vim tem.sh
echo ${12}  #打括号意思是第几个,$符号是一个参数标志。
bash tem.sh p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12

则会打印出p12

三、通配符

常见的*
比如echo s20220323*
则会把当前目录下前缀s20220323的所有文件都显示出来。echo s20220323[1,2]*
则会打印s202203231和s202203232为前缀的所有文件。

四、标准的头文件。

在sh文件里最前面的几行。包括作者,练习方式,版本,参数等。
比如# /bin/bash

五、sh里面的内容

1. 判断语句。

因为使用这个软件的人也许胡乱输入,或者错误输入,所以要针对的给出提示语,让操作者知道有错误了。

2. 什么是循环

理解while 和for(理解得不好,还需要后续学习)

for in i {20..27}; do echo SRR10395*${i}.fastq.gz; done
就是把SRR1039520-SRR1039527这几个fq文件名显示出来。

3.ln命令

是linux系统中一个非常重要命令,英文全称是“link”,即链接的意思,它的功能是为某一个文件在另外一个位置建立一个同步的链接。 一种是hard link,又称为硬链接;另一种是symbolic link,又称为符号链接。

通俗一点理解,可以把硬链接当成源文件的副本,他和源文件一样的大小,但是事实上却不占任何空间。符号链接可以理解为类似windows一样的快捷方式。

六、shell十三问

众神们已经给了很多解释,我只记录自己理解的。https://segmentfault.com/a/1190000004324819
https://blog.csdn.net/xhtchina/article/details/123097589

1.为何叫做shell?

电脑通过“操作系统(OS,Opertating System)这个软件来驱动 ,linux是一个操作系统,我们称之为“核心(kernel)。但是我们不能直接操作kernel(大概是因为我们不能直接输入二进制的命令吧),只能通过一个“外壳”程序,就是 Shell 来与 Kernel 沟通。shell是一个使用者与系统的互动界面(interface),使用者用命令行(command line)来使用系统干活。因此,shell的最简单的定义就是---命令解释器(Command Interpreter)。
不同的 OS 使用不同的 Kernel;同一个 kernel 之上,也可以使用不同的 Shell,常见的 Shell 有sh、bash、csh、ksh 等。大部份的Linux系统的预设shell都是bash。

2.shell prompt(PS1)与 Carriage Return(CR)的关系?

成功登录一个 Shell 终端后,光标左边部分称之为提示符 Prompt,通常一般用户使用$。shell prompt的意思很简单:是shell告诉使用者:您现在可以输入命令行了。
cursor也称为游标,是指示键盘在命令行所输入的位置,使用者每输入一个键,cursor就往后移动一格,直到碰到命令行读进CR(Carriage Return,由Enter键产生)字符为止。CR的意思也很简单:是使用者告诉shell:老兄你可以执行我的命令了。

3.别人echo,你也echo,试问 echo 知多少?

标准的命令行(command line)包含三个部件:command_name option argument
echo命令是将argument送出至标准输出(STDOUT),通常就是在显示器(monitor)上输出。echo在预设上,在显示完argument之后,还会送出一个换行符号(new-line charactor)
如果 echo -n argument,则不会换行了。
再例如:用-e来表示反斜杠为控制字符转换的符号。\t 是表格跳位字符,相当于tab键;\n 是换行字符。
$ echo -e "a\tb\tc\nd\te\tf"
a b c
d e f
注意还有很多类似的反斜杠加字母,作为控制字符的。如\b 是退位字符,也就是BACKSPACE。

4. “”(双引号)与''(单引号)差在哪?

在命令行中用IFS(Internal Field Seperator)分割不同字段。在命令中,如有特殊字符(meta)是要先处理的。除了IFS和CR,下面meta这些很常用。

= : 设定变量。
$ : 作变量或运算替换(请不要与shell prompt搞混了)。
< : 重导向stdin。 > : 重导向stdout。
| : 命令管线。
& : 重导向file descriptor,或将命令置于背境执行。
() : 将其内的命令置于nested subshell执行,或用于运算或命令替换。
{} : 将其内的命令置于non-named function中执行,或用在变量替换的界定范围。

; : 在前一个命令结束时,而忽略其返回值,继续执行下一个命令。
&& : 在前一个命令结束时,若返回值为true,继续执行下一个命令。
|| : 在前一个命令结束时,若返回值为false,继续执行下一个命令。
!: 执行history列表中的命令

在命令行中有时候需要把这些meta关闭,因为不关闭就会先执行这些mata。那就要用到单引号和双引号和escape。
hard quote:' '(单引号),凡在hard quote中的所有meta均被关闭;
soft quote:“”(双引号),在soft quote中大部份meta都会被关闭,但某些则保留(如$);
escape : \(反斜线),只有紧接在escape(跳脱字符)之后的单一meta才被关闭。

meraners-MacBook:~ meraner$ A='B
> C'
meraners-MacBook:~ meraner$ echo $A #什么都不加输出变量A的值。
B C
meraners-MacBook:~ meraner$ echo "$A" #双引号保留$的meta功能。
B
C
meraners-MacBook:~ meraner$ echo '$A' #单引号关闭了$的meta功能。
$A

meraners-MacBook:~ meraner$ A=B\ C#用反斜杠取消space的meta功能,成为单纯的空格
meraners-MacBook:~ meraner$ echo "$A"
B C
$ A=B\ C
$ echo ' "$A" ' #最外面的是单引号,先执行最外面的命令,则把里面的所有都作为文字输出。
"$A"
$ echo " '$A' " #最外面的是双引号,先执行最外面的命令,把里面的$的变量替换功能保留下来。
'B C'

还记得day9学的awk命令么?用来把文本中的列拎出来的命令哦。用到了单引号。

awk '{print $1":"$2","$3}' test.bed'
具体解释如下:
{ }是将其内一系列command line置于不具名的函式中执行(可简单视为command block),但awk命令却要用大括号来 区分出awk的命令区段(BEGIN,MAIN,END)。上面的hard quote(单引号)就是将原本的{、<space>、$}这几个shell meta关闭,避免掉在shell中遭到处理,而完整的成为awk参数中的command meta。

$ awk '{print $0}' 1.txt
awk "{print \$0}" 1.txt
awk \{print\ \$0\} 1.txt

这三个命令效果一样。单引号和双引号,大不同哦。

5. var=value? export 前后差在哪?

5.1对变量的深入理解

今天的第一部分就提到,变量(variable)就是用一个特定的“名称”(name)来存取一段可以变化的“值”(value)。
变量替换
在命令行中使用者可以使用符号加上变量名称(除了在用=号定义变量名称之外),将变量值给替换出来,然后再重新组建命令行。 可以用命令行的变量替换能力来“扩充”(append)变量值。比如之前对环境变量进行添加的时候,有过类似下面的操作。`PATH=PATH:/~data/zds209/bin`。
使用区隔符号(:)来达到扩充目的。如果不用这个区隔符号,会怎样呢?

A=BCD
A=$AE #意思是A被重新赋值为AE这个变量的值。
echo $A
    #结果是什么也没有,因为没有 AE这个变量。。

A=BCD
A=${A}E   #用{}将变量名称的范围给明确定义出来echo $A
BCDE

5.2 export是个啥?

在当前shell中所定义的变量,均属于“本地变量”(local variable),只有经过export命令的“输出”处理,才能成为环境变量(environment variable)

$ A=B
$ export A # 这时候A才能作为一个环境变量供其后的命令使用。
$ A=B
$ B=C
$ export $A #这时候B作为环境变量了,因为先执行了$A这个变量的替换操作。相当于export B。

5.3 变量取消

unset A 就是把A变量从环境变量中取消。

$ A=B
$ B=C
$ unset $A #因为先执行$A这个替换,所以实际上取消的是变量B。

变量替换有点儿烧脑。下面对A为null 和unset A的区别加以解释。

$ A=   #变量A值为空null,但是存在这个变量A哦。只不过是null value
$ B=${A=BCD} #既然上面把变量A设定为空,就是不可能有数值,也就不能被赋值了。把BCD赋值给A的这件事儿没发完成啊,A是空滴。。
$ echo $A
                   #A为null(空值),有A这个变量,但是是空的。
$ echo $B
                    #既然A是空,不能被赋值,B展示出A的结果也是空啦。


$ unset A   #变量A取消了,不存在了。。
$ B=${A=BCD} #没有A这个变量的情况下,bash把BCD赋值给了A,然后又把$A赋值给了B。
$ echo $A
BCD
$ echo $B
BCD

简单说,就是如果之前A变量赋值过了,哪怕赋值的是null或者0,或者别的什么,后面B={A=...} 这个里面点点点是啥都没用了。都要依靠前面A的值是啥而定。 如果A压根就没这个变量,那么B={A=...} 这个命令就是制造了一个变量B,同时制造了变量A,并赋值给A和B。如下:

$ A=xyz
$ B=${A=BCD}
$ echo $A
xyz
$ echo $B
xyz

6. exec 跟 source 差在哪?

6.1 行程(process)

我们所执行的任何程序,都是由父行程(parent process)所产生出来的一个子行程(child process)即sub-shell,子行程在结束后,将返回到父行程去。此一现像在Linux系统中被称为fork。
环境变量只能从父行程到子行程单向继承。换句话说:在子行程中的环境如何变更,均不会影响父行程的环境。

6.2脚本(script)

将你平时在shell prompt后所输入的多行command line依序写入一个文件去。其中再加上一些条件判断、互动界面、参数运用、函数调用等等技巧,得以让script更加“聪明”的执行,但若撇开这些技巧不谈,我们真的可以简单的看成script只不过依次执行预先写好的命令行而已。

6.3 source命令

我们跑一个脚本的时候会产生相应子进程( child process)。 当child结束后,会返回parent,但parent的环境是不会因child的改变而改变的。 环境元数很多,凡举effective id,variable,workding dir等等。

source就是让script在当前shell内执行、而不是产生一个sub-shell来执行。由于所有执行结果均于当前shell内完成,若script的环境有所改变,当然也会改变当前环境了﹗
还记得改变了.bashrc 里面的设定后,要source .bashrc。大概就是这个意思吧。

6.4 exct和source/fork的差别

exec也是让script在同一个行程上执行,但是原有行程则被结束了。也就是简而言之:原有行程会否终止,就是exec与source/fork的最大差异了。

7. ( ) 与 { } 差在哪?

“命令群组”(command group)是将多个命令集中处理。
()与{ }这两对符号都可将多个命令作群组化处理。
( ) 将command group置于sub-shell去执行,也称nested sub-shell,所作的修改是临时的,且不想影响原有或以后的设定。
{ } 则是在同一个shell内完成,也称为non-named command group

function,就是用一个名字去命名一个command group,然后再调用这个名字去执行command group。
在shell操作中,需要不断的重覆执行某些命令,我们首先想到的,或许是将命令写成命令脚本(shell script)。不过,我们也可以写成function,然后在command line中打上function_name就可当一舨的script来使用了。我们可以自行定义许许多多好用的function,再集中写在特定文件中,然后,在其他的script中用source将它们加载并反复执行。

第11问以后:
https://segmentfault.com/a/1190000004325734?utm_source=sf-similar-article

上一篇 下一篇

猜你喜欢

热点阅读