平时用惯了被人搭建的环境、脚本,总是make xxx/run xxx,都忘记了如何自己搭建了。现在开始要自己学习下啦~
第一件就是terminal设置,为我们常见的命令设置一些快捷键,如gvim、cd ..、ls -l等等。我是在terminal中写一个bash脚本。可以在terminal中输入echo $SHELL或echo $0或env命令来判断现在terminal是csh还是bash。$0是指当前正在运行的进程,所以,当在 shell 中输出 $0 时,即是 shell 的名称。但是,如果是在脚本中输出,则是脚本的名字。如下图:
.如果想切换terminal的shell设置:
终端命令:chsh -s /bin/bash和chsh -s /bin/csh退出以后重登陆将会更改默认SHELL。
对于bash shell的快捷键和环境变量设置可以在.bashrc文件中设置,该文件在home目录下,为隐藏文件。对于c shell的则在.cshrc中设置。如下为设置的环境变量和alias举例。
对于csh设置环境变量命令是:setenv FILTERS FILTERBIN.RES,对于bash为:export FILTERS=FILTERBIN.RES。对于常用的环境变量建议写到.shrc文件中。
bash脚本第一行会有#!/bin/bash,指定了程序将使用的解释器。linux有很多解释器,如bash、zsh、sh、csh和ksh等。可以在terminal中输入:cat /etc/shells,看系统支持哪些shell。如果在脚本中不包含解释器,则使用默认shell执行命令,因此代码有可能正常执行,使用echo $SHELL可以查看目前运行的解释器。在shell中,注释以#开始,#后面的内容都会被忽略,但#!除外。
变量:
变量是指向内存的一块区域,变量有对应的变量名和值,可以存储一些可能更改的数据。在shell中定义变量不需要指定变量的类型。变量名区分大小写,要使用变量,必须在变量前面加$符号。如: VARIABLE=“value” echo $VARIABLE echo ${VARIABLE}。
提示:1、可以把命令执行后的输入结果赋值给一个变量,如:LIST=$(ls),SERVER=$(hostname);
2、read -p命令可以用于从接收键盘的输入,如: read -p “input a strin” NAME,从键盘输入的信息会存储在NAME当中。
测试(判断):
测试主要用于条件判断。[ condition-to-test-for ],如[ -e /etc/passwd ],注意的是[]前后必须有空格,[ -e /etc/passwd]是错误的写法。
1、文件测试操作
-d FILE_NAM # True if FILE_NAM is a directory
-e FILE_NAM # True if FILE_NAM exists
-f FILE_NAM # True if FILE_NAM exists and is a regular file
-r FILE_NAM # True if FILE_NAM is readable
-s FILE_NAM # True if FILE_NAM exists and is not empty
-w FILE_NAM # True if FILE_NAM has write permission
-x FILE_NAM # True if FILE_NAM is executable
2、字符串测试操作
-z STRING # True if STRING is empty
-n STRING # True if STRING is not empty
STRING1 = STRIN2 # True if strings are equal
STRING1 != STRIN2 # True if strings are not equal
3、算术测试操作
var1 -eq var2 # True if var1 is equal to var2
var1 -ne var2 # True if var1 not equal to var2
var1 -lt var2 # True if var1 is less than var2
var1 -le var2 # True if var1 is less than or equal to var2
var1 -gt var2 # True if var1 is greater than var2
var1 -ge var2 # True if var1 is greater than or equal to var2
判断比较:
1、if语句
if [ condition-is-true ]
then
command 1
command 2
...
...
command N
fi
if-else-fi
if [ condition-is-true ]
then
command 1
elif [ condition-is-true ]
then
command 2
elif [ condition-is-true ]
then
command 3
else
command 4
fi
case语句可以实现和if
一样的功能,但是当条件判断很多的时候,使用if
不太方便,比如使用if
进行值的比较
case "$VAR" in
pattern_1)
# commands when $VAR matches pattern 1
;;
pattern_2)
# commands when $VAR matches pattern 2
;;
*)
# This will run if $VAR doesnt match any of the given patterns
;;
esac
shell脚本支持逻辑与和逻辑或
逻辑与 &&
逻辑或 ||
Example:mkdir tempDir && cd tempDir && mkdir subTempDir
这个例子中,如果创建tempDir成功,执行后面的cd
,继续创建subTempDir
循环:
可以通过循环执行同一个代码块很多次。
1. for
循环
for VARIABLE_NAME in ITEM_1 ITEM_N
do
command 1
command 2
...
...
command N
done
Example
#!/bin/bash
COLORS="red green blue"
for COLOR in $COLORS
do
echo "The Color is: ${COLOR}"
done
Another Example,记住for后面必须带两个括号
for (( VAR=1;VAR<N;VAR++ ))
do
command 1
command 2
...
...
command N
done
在当前所有txt文件前面追加new
实现重命名
#!/bin/bash
FILES=$(ls *txt)
NEW="new"
for FILE in $FILES
do
echo "Renaming $FILE to new-$FILE"
mv $FILE $NEW-$FILE
done
while
循环
当所给的条件为true
时,循环执行while
里面的代码块
while [ CONNDITION_IS_TRUE ]
do
# Commands will change he entry condition
command 1
command 2
...
...
command N
done
判断条件可以是任意的测试或者命令,如果测试或命令返回0,则表示条件成立,如果为非0则退出循环,如果一开始条件就不成立,则循环永远不会执行。
例子 一行一行读取文件内容
#!/bin/bash
LINE=1
while read CURRENT_LINE
do
echo "${LINE}: $CURRENT_LINE"
((LINE++))
done < /etc/passwd
# This script loops through the file /etc/passwd line by line
注意⚠️continue
用于结束本次循环break
用于结束整个循环
参数传递:
当我们运行脚本的时候,可以传递参数供脚本内部使用$ ./script.sh param1 param2 param3 param4
这些参数将被存储在特殊的变量中
$0 -- "script.sh"
$1 -- "param1"
$2 -- "param2"
$3 -- "param3"
$4 -- "param4"
$@ -- array of all positional parameters
$# -- 传递给脚本总的参数数目;
$* -- 传递给脚本总的参数组成的字符串
$? -- 上一个代码或shell脚本在shell中退出的情况,如果正常退出则为0,非正常退出则为非0值;$?其实就是存储退出状态吗,任何命令执行完成后都会产生一个退出状态码,范围0~255,状态码可以用来检查错误,0表示正确执行并正常退出。当然我们可以自定义退出状态码,默认的状态码是上一条命令执行的结果,我们可以通过exit来自定义状态码:exit 0、exit 1、exit 2、... 、exit 255.
这些变量可以在脚本中的任何地方使用,就像其他全局变量一样
函数:
可以把一些常用的带有关联性的命令和语句封在一个函数内,从程序的其他地方调用,函数必须先定义后调用。通常可以把函数定义在程序开始或主程序之前。
语法:
function function_name() {
command 1
command 2
command 3
...
...
command N
}
调用函数只需简单的给出函数名字
#!/bin/bash
function myFunc () {
echo "Shell Scripting Is Fun!"
}
myFunc # call
函数的参数传递:
和脚本一样,也可以给函数传递参数完成特殊的任务,第一个参数存储在变量$1
中,第二个参数存储在变量$2
中...,$@
存储所有的参数,参数之间使用空格分割 myFunc param1 param2 param3 ...
变量的作用范围:
全局变量: 默认情况下,shell中的变量都定义为全局变量,你可以从脚本中的任何位置使用变量,但是变量在使用之前必须先定义本地变量: 本地变量只能在方法内部访问,可以通过local
关键词定义一个本地变量,定义一个本地变量的最佳实践是在函数内部。
通配符:
使用通配符可以完成特定的匹配
一些常用的通配符*
可以通配一个或多个任意字符
*.txt
hello.*
great*.md
?
匹配一个字符
?.md
Hello?
[]
匹配括号内部的任意一个字符
He[loym], [AIEOU]
[!]
不匹配括号内的任何字符
`[!aeiou]`
预先定义的通配符 [[:alpha:]]
[[:alnum:]] [[:space:]]
[[:upper:]]] [[:lower:]]
[[:digit:]]
匹配通配符 有些情况下我们想匹配*
或?
等特殊字符,可以使用转义字符\*\?
调试:
bash提供一些可选项帮助你调试程序Some Options:
1. -x
option
它在执行时打印命令和参数。它被称为打印调试,跟踪或x跟踪。我们可以通过修改第一行来使用它
2. -e
option
它代表“出错”。如果命令以非零退出状态退出,这将导致脚本立即退出。
3. -v
option
它在读取时打印shell命令/输入行。
注意:这些选项可以组合使用,一次可以使用多个选项!
#!/bin/bash-xe
#!/bin/bash-ex
#!/bin/bash-x-e
#!/bin/bash-e-x