通过可执行程序进行执行
chmod +x ./test.sh
./test.sh
赋予test.sh脚本文件执行权限,然后在脚本所在目录,通过./test.sh执行脚本。不能直接test.sh是因为直接调用他会去系统PATH环境变量里去寻找执行文件。
通过sh解释器来执行脚本
/bin/sh test.sh
也可以直接输入sh test.sh。因为通常情况下/bin目录已经被配置到了PATH中。
your_name="zhangsan"
your_name="zhangsan"
echo $your_name
echo ${your_name}
变量名外面的花括号{ }是可选的,加花括号{ }是为了帮助解释器识别变量的边界
已定义的变量,可以被重新定义.
使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。
当我尝试vim readOnlyVar.sh更改只读变量时:
#!/bin/bash
myString="jkchou"
readonly myString
myString="hh"
系统会提示报错:
[root@localhost variable]# sh readOnlyVar.sh
readOnlyVar.sh: line 5: myString: readonly variable
使用unset命令可以删除变量。
unset variable_name
变量被删除后不能再次使用。unset 命令不能删除只读变量。
Shell中使用$来引用变量
echo $variable_name
需要注意的是双引号""和单引号’'在其引用变量时要注意,效果和直接使用引号输出略有差异,如下述程序:
#!/bin/sh
var="Hello"
echo "hello"
echo 'hello'
echo "$var"
echo '$var'
输出结果为:
[root@localhost variable]# sh referVar.sh
hello
hello
Hello
$var
直接使用双引号和单引号输出常量串,直接输出,但是使用变量引用时,双引号会引用其中的变量值,输出变量的值,而单引号不会引用变量,而是直接输出相应的字符。其次,单引号中的内容不能出现转义字符的单引号的,但是双引号就可以出现转义双引号。例如:
echo 'hello everyone, i am gg '
#正确,将输出hello everyone, i am gg
echo 'hello everyone, i am \'gg\' '
#错误,将报错:unexpected EOF while looking for matching `''
echo 'hello everyone,''i am gg '
#正确,这属于字符串拼接,虽然是两对'',但是没有嵌套在一起,将输出这句话
echo "hello everyone, \"i am gg\" "
#正确,将输出hello everyone, "i am gg "
Shell中还有好多常见的引用,比如有$var、${var}、${#var}、${var:start_char:length}等等,大都是对字符串进行操作的,这里不做列出,想要了解的找Shell字符串相关内容,需要注意的是,如${#var}这种,花括号{}是不能省略的,否则无法输出想要的返回值。
Shell脚本中通过echo输出变量,通过read关键字读取变量。当然,是从命令行读取。
#!/bin/sh
read var
echo "your input is :"$var
如果我输入的是jkchou,那么将在控制台有如下结果:
[root@localhost variable]# sh readVar.sh
jkchou
your input is :jkchou
上述脚本中的变量通常被称为局部变量或者本地变量,Shell中还存在一些独特的变量,包括环境变量、位置变量、标准变量和特殊变量。下面,我只挑经常用得到的环境变量来具体说一说,其他几个特殊的变量只做个概述。
位置变量即执行脚本时,传入脚本中对应脚本位置的变量。类似于调用函数的时候,函数的参数,引用方法为$+参数位置,比如$0、$1、$2等。$0比较特殊,代表的是脚本的名称,其余$1代表的是脚本的第一个参数,以此类推。比如:
#!/bin/sh
echo "name of the script:"$0
echo "first variable:"$1
echo "second variable:"$2
echo "third variable:"$3
echo "fourth variable:"$4
执行这个脚本:
[root@localhost variable]# sh varSorted.sh A B C
name of the script:varSorted.sh
first variable:A
second variable:B
third variable:C
fourth variable:
可以看到,不输入第四个参数的时候是不会打印出$4的,同理,多输入第五个,也不会打印出第五个参数。可以配合shift,使参数左移一位,上述脚本,如果加入个shift,则只会打印出B和C,A就被左移出去了,两个shift就是左移两次。
标准变量,就是环境变量。细看的话,属于系统环境变量,在bash环境建立时生成,在/etc/profile 文件中可以查看系统中的标准环境变量。
变量名和含义如下:
例子如下:
#!/bin/bash
echo "number of variables:"$#
echo "pre commands' situation:"$?
echo "cur script's processes identity number:"$$
echo "run last commands:"$!
echo "all the paramaters:"$*
运行结果:
[root@localhost variable]# vim specialVar.sh
[root@localhost variable]# sh specialVar.sh A B C
number of variables:3
pre commands' situation:0
cur script's processes identity number:66446
run last commands:
all the paramaters:A B C
讲在前面:以下引用内容来自man bash,后续内容完全为个人理解与查阅得到。
FILES
/bin/bash
The bash executable
/etc/profile
The systemwide initialization file, executed for login shells
/etc/bash.bash_logout
The systemwide login shell cleanup file, executed when a login
shell exits
~/.bash_profile
The personal initialization file, executed for login shells
~/.bashrc
The individual per-interactive-shell startup file
~/.bash_logout
The individual login shell cleanup file, executed when a login
shell exits
~/.inputrc
Individual readline initialization file
环境变量分为系统环境变量和用户环境变量
bash命令与应用程序命令的执行是需要运行环境的,这些环境的构成正是环境变量。举个例子,当我们在编写java程序时,需要jdk,jdk中的bin下有一个叫javac的二进制文件,通过javac javafile_name 可以实现对这个.java文件的编译。如果没有配置环境变量,我们只能指定这个bin目录下的javac文件来编译java文件,比如:
在hello.java的目录下输入:
/usr/java/jdk1.8.0_151/bin/javac hello.java
或者
cd /usr/java/jdk1.8.0_151/bin/
javac ~/Desktop/hello.java
以及使用/usr/local/bin、/usr/bin、/bin下等等的指令时,这些都是默认配置到环境变量中的,否则我们将无法使用与系统交互/应用交互的各种指令;除此之外,许多应用的运行环境也需要一些执行程序的支持,当在其安装目录找不到时,就会去环境变量里寻找,找不到就无法实现某些功能。
Linux系统环境变量的配置在:/etc/profile、/etc/profile.d、/etc/bashrc。他们的区别在于启动时机和作用对象的不同。经过我的查阅,概述性的总结如下:
/etc/profile : 对所有用户生效;当用户第一次登录操作系统,该文件被执行;不建议在此配置环境变量。
/etc/profile.d : 对所有用户生效;每次执行/etc/profile时,该文件都会被执行,其内部有许多脚本文件,被执行时,也是执行该目录下的所有脚本文件;建议在此配置环境变量,易于修改和移植,添加删除修改方便,耦合度低。
可以在profile中看到执行profile.d的代码:
for i in /etc/profile.d/*.sh ; do
if [ -r "$i" ]; then
if [ "${-#*i}" != "$-" ]; then
. "$i"
else
. "$i" >/dev/null 2>&1
fi
fi
done
/etc/bashrc : 对所有用户生效;每当用户运行bash shell (可以理解为终端,大多Linux版本默认以bash作为默认shell),这个文件就会被执行,也就是说,每当用户shell执行了bash脚本和终端,这个文件被执行,并对所有用户生效;不建议在此配置环境变量。
登录shell和非登录shell的区别:
通过bash、sh等指令直接进入的命令行模式均属于非登录shell,说人话我理解的就是没有输入账户密码的,就属于非登录。
Linux用户环境变量的配置在: ~/.bash_profile、~/.bash_logout、~/.bashrc
[jkchou@localhost /]$ ls -l ~/.bash*
-rw-------. 1 jkchou jkchou 10748 Oct 23 04:32 /home/jkchou/.bash_history
-rw-r--r--. 1 jkchou jkchou 18 May 10 2016 /home/jkchou/.bash_logout
-rw-r--r--. 1 jkchou jkchou 176 May 10 2016 /home/jkchou/.bash_profile
-rw-r--r--. 1 jkchou jkchou 124 May 10 2016 /home/jkchou/.bashrc
~/.bash_profile : 和/etc/profile类似,不过是用户级别的,只对当前~用户生效;当用户登录时,该文件被执行一次;紧接着它还会调用一次~/.bashrc;建议在此配置环境变量。默认下的Cent OS6.7的bash_profile文件内容如下:
[jkchou@localhost /]$ cat ~/.bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH
~/.bashrc : 和/etc/bashrc类似,是用户级别的;当登录时或者打开新的shell 时,该文件会被加载一次,登录shell和非登录shell都可以使用.bashrc中的内容;不建议在此配置环境变量。
~/.bash_logout : 用户级别;当退出bash shell时,执行它(看这个调用时机也知道,不能在它里面放正常内容了吧?233)。
综上所述,通常情况下,登录用户,可以得出如下结论的执行时机:
/etc/profile -> /etc/profile.d -> /etc/bashrc -> ~/.bash_profile -> ~/.bashrc
除此之外,使用export可以设置和现实环境变量,但他设置的环境变量是会话级的,关闭当前终端后,就会失效了。
由于我用的是Mac操作系统,虽然都是基于Unix内核,但是我还是想说说我个人的理解,Mac在2019年以zsh作为默认的shell,zsh就是在bash的基础上进行了大量的改进,同时加入了bash、ksh和tcsh的某些功能。所以,当我在Mac的bash_profile中配置环境变量后,无论怎么样,它并不会生效,这是因为Mac并没有自动的在某个地方调用bash相关的指令,而是调用的~/.zshrc 和~/.zprofile ,所以,有三种方法,可以调用bash写的环境变量:
但是Mac和Linux还是有很大的区别的,以下内容截自官方文档:
STARTUP/SHUTDOWN FILES
Commands are first read from /etc/zshenv; this cannot be overridden.
Subsequent behaviour is modified by the RCS and GLOBAL_RCS options; the
former affects all startup files, while the second only affects global
startup files (those shown here with an path starting with a /). If one
of the options is unset at any point, any subsequent startup file(s) of
the corresponding type will not be read. It is also possible for a file
in $ZDOTDIR to re-enable GLOBAL_RCS. Both RCS and GLOBAL_RCS are set by
default.
Commands are then read from $ZDOTDIR/.zshenv. If the shell is a login
shell, commands are read from /etc/zprofile and then $ZDOTDIR/.zprofile.
Then, if the shell is interactive, commands are read from /etc/zshrc and
then $ZDOTDIR/.zshrc. Finally, if the shell is a login shell,
/etc/zlogin and $ZDOTDIR/.zlogin are read.
………………
可以看出,首先执行的是/etc/zshenv,想了解更多直接man zsh
Shell中实现算术运算一般通过两个命令:let和expr
直接上例子:
#!/bin/bash
i=1
echo "i="$i
let i=i+2
echo "i="$i
let "i=i+4"
echo "i="$i
i=i+3
echo "i="$i
结果:
[jkchou@localhost shell Test]$ sh letTest.sh
i=1
i=3
i=7
i=i+3
let也可以用((算数表达式))来代替,比如:
((i+=3))
直接上代码:
#!/bin/bash
a=10
b=10
c=`expr $a + $b`
echo "c="$c
需要注意的是,``是tab上,!左边的那个符号,不是单引号!!,除此之外, a 、 a、 a、b和算数运算符+之间需要有空格,否则会原样输出:c=10+10
结果:
[jkchou@localhost shell Test]$ sh exprTest.sh
c=20
该文章最终目的是自我学习与提升,不做任何商业用途,转载还请标明出处,写作不易。如有错误欢迎指出,毕竟我只是个本科菜鸟。