day13 脚本编辑-后面shell十三问太烧脑了
一、理解“变量”
给一个字符串进行赋值,比如: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里面有什么参数了。比如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)。
变量替换
在命令行中使用者可以使用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=...} 这个命令就是制造了一个变量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