Shell 学习

shell入门基础
1.建立和运行shell程序
什么是shell程序呢? 简单的说shell程序就是一个包含若干行
shell或者linux命令的文件.
象编写高级语言的程序一样,编写一个shell程序需要一个文本编辑器.如VI等.
在文本编辑环境下,依据shell的语法规则,输入一些shell/linux命令行,形成一个完整
的程序文件.
执行shell程序文件有三种方法
(1)#chmod +x file(在/etc/profile中,加入export PATH=${PATH}:~/yourpath,就可以在命令行下直接运行,像执行普通命令一样)
(2)#sh file
(3)# . file
(4)#source file
在编写shell时,第一行一定要指明系统需要那种shell解释你的shell程序,如:#! /bin/bash,
#! /bin/csh,/bin/tcsh,还是#! /bin/pdksh .
2.shell中的变量
(1)常用系统变量
$ # :保存程序命令行参数的数目
$ ? :保存前一个命令的返回码
$ 0 :保存程序名
$ * :以("$1 $2...")的形式保存所有输入的命令行参数
$ @ :以("$1""$2"...)的形式保存所有输入的命令行参数
(2)定义变量
shell语言是非类型的解释型语言,不象用C++/JAVA语言编程时需要事先声明变量.给一
个变量赋值,实际上就是定义了变量.
在linux支持的所有shell中,都可以用赋值符号(=)为变量赋值.
如:
abc=9 (bash/pdksh不能在等号两侧留下空格 )
set abc = 9 (tcsh/csh)
由于shell程序的变量是无类型的,所以用户可以使用同一个变量时而存放字符时而存放
整数.
如:
name=abc (bash/pdksh)
set name = abc (tcsh)
在变量赋值之后,只需在变量前面加一个$去引用.
如:
echo $abc
(3)位置变量
当运行一个支持多个命令行参数的shell程序时,这些变量的值将分别存放在位置变量里.
其中第一个参数存放在位置变量1,第二个参数存放在位置变量2,依次类推...,shell保留
这些变量,不允许用户以令外的方式定义他们.同别的变量,用$符号引用他们.

3.shell中引号的使用方法
shell使用引号(单引号/双引号)和反斜线("")用于向shell解释器屏蔽一些特殊字符.
反引号(")对shell则有特殊意义.
如:
abc="how are you" (bash/pdksh)
set abc = "how are you" (tcsh)
这个命令行把三个单词组成的字符串how are you作为一个整体赋值给变量abc.
abc1='@LOGNAME,how are you!' (bash/pdksh)
set abc1='$LOGNAME,how are you!' (tcsh)
abc2="$LOGNAME,how are you!" (bash/pdksh)
set abc2="$LOGNAME,how are you!" (tcsh)
LOGNAME变量是保存当前用户名的shell变量,假设他的当前值是:wang.执行完两条命令后,
abc1的内容是:$LOGNAME, how are you!.而abc2的内容是;wang, how are you!.
象单引号一样,反斜线也能屏蔽所有特殊字符.但是他一次只能屏蔽一个字符.而不能屏蔽
一组字符.
反引号的功能不同于以上的三种符号.他不具有屏蔽特殊字符的功能.但是可以通过他将
一个命令的运行结果传递给另外一个命令.
如:
contents=`ls` (bash/pdksh)
set contents = `ls` (tcsh)
4.shell程序中的test命令
在bash/pdksh中,命令test用于计算一个条件表达式的值.他们经常在条件语句和循环
语句中被用来判断某些条件是否满足.
test命令的语法格式:
test expression
或者
[expression]

在test命令中,可以使用很多shell的内部操作符.这些操作符介绍如下:
(1)字符串操作符 用于计算字符串表达式
test命令 | 含义
-----------------------------------------
Str1 = str2 | 当str1与str2相同时,返回True
Str1! = str2| 当str1与str2不同时,返回True
Str | 当str不是空字符时,返回True
-n str | 当str的长度大于0时,返回True
-z str | 当str的长度是0时,返回True
-----------------------------------------
(2)整数操作符具有和字符操作符类似的功能.只是他们的操作是针对整数
test表达式 | 含义
---------------------------------------------
Int1 -eq int2|当int1等于int2时,返回True
Int1 -ge int2|当int1大于/等于int2时,返回True
Int1 -le int2|当int1小于/等于int2时,返回True
Int1 -gt int2|当int1大于int2时,返回True
Int1 -ne int2|当int1不等于int2时,返回True
-----------------------------------------
(3)用于文件操作的操作符,他们能检查:文件是否存在,文件类型等
test表达式 | 含义
------------------------------------------------
-d file |当file是一个目录时,返回 True
-f file |当file是一个普通文件时,返回 True
-r file |当file是一个刻读文件时,返回 True
-s file |当file文件长度大于0时,返回 True
-w file |当file是一个可写文件时,返回 True
-x file |当file是一个可执行文件时,返回 True
------------------------------------------------
(4)shell的逻辑操作符用于修饰/连接包含整数,字符串,文件操作符的表达式
test表达式 | 含义
----------------------------------------------------------
! expr |当expr的值是False时,返回True
Expr1 -a expr2|当expr1,expr2值同为True时,返回True
Expr1 -o expr2|当expr1,expr2的值至少有一个为True时,返回True
-----------------------------------------------------------
注意:
tcsh shell 不使用test命令,但是tcsh中的表达式同样能承担相同的功能.tcsh
支持的表达式于C中的表达式相同.通常使用在if和while命令中.
tcsh表达式 | 含义
-------------------------------------------------------
Int1 <= int2 |当int1小于/等于int2时,返回True
Int1 >= int2 |当int1大于/等于int2时,返回True
Int1 < int2 |当int1小于int2时,返回True
Int1 > int2 |当int1大于int2时,返回True
Str1 == str2 |当str1与str2相同时,返回True
Str1 != str2 |当str1与str2不同时,返回True
-r file |当file是一个可读文件时,返回True
-w file |当file是一个可写文件时,返回True
-x file |当file是一个可执行文件时,返回True
-e file |当file存在时,返回True
-o file |当file文件的所有者是当前用户时,返回True
-z file |当file长度为0时,返回True
-f file |当file是一个普通文件时,返回True
-d file |当file是一个目录时,返回True
Exp1 || exp2 |当exp1和exp2的值至少一个为True时,返回True
Exp1 && exp2 |当exp1和exp2的值同为True时,返回True
! exp |当exp的值为False时,返回True
-------------------------------------------------------

/***************************************************/

先不要管Shell的版本,来看看Shell 变量,在Shell中有三种变量:系统变量,环境变量,用户变量。其中用户变量在编程过程中使用最多,系统变量在对参数判断和命令返回值判断会使用,环境变量主要是在程序运行的时候需要设置。

1 系统变量

Shell常用的系统变量并不多,但却十分有用,特别是在做一些参数检测的时候。下面是Shell常用的系统变量

表示方法 描述
$n $1 表示第一个参数,$2 表示第二个参数 ...
$# 命令行参数的个数
$0 当前程序的名称
$? 前一个命令或函数的返回码
$* 以"参数1 参数2 ... " 形式保存所有参数
$@ 以"参数1" "参数2" ... 形式保存所有参数
$$ 本程序的(进程ID号)PID
$! 上一个命令的PID

其中使用得比较多得是 $n $# $0 $? ,看看下面的例子: BeautifierPlugin Error: Unable to handle "bash" syntax.

#!/bin/sh
#This file is used to explain the shell system variable.
echo "the number of parameter is $# ";
echo "the return code of last command is $?";
echo "the script name is $0 ";
echo "the parameters are $* ";
echo "$1 = $1 ; $2 = $2 ";

下面是运行结果:

BeautifierPlugin Error: Unable to handle "bash" syntax.

-bash-2.05b$ ./chapter2.1.sh winter stlchina
the number of parameter is 2 
the return code of last command is 0
the script name is ./chapter2.1.sh 
the parameters are winter stlchina 
$1 = winter ; $2 = stlchina 

这个例子太简单了,一点也不实用,下面来个实用的,如果你看不懂,没有关系,后面的内容会有详细解释。 BeautifierPlugin Error: Unable to handle "bash" syntax.

#!/bin/sh
if [ $# -ne 2 ] ; then
echo "Usage: $0 string file";
exit 1;
fi
grep $1 $2 ;
if [ $? -ne 0 ] ; then
echo "Not Found "$1" in $2";
exit 1;
fi
echo "Found "$1" in $2";

上面的例子中使用了$0 $1 $2 $# $? 等变量,下面是程序的解释:

  1. 判断运行参数个数,如果不等于2,显示使用"用法帮助", 其中 $0 表示就是脚本自己。
  2. 用grep 在$2 文件中查找$1 字符串。
  3. 判断前一个命令运行后的返回值(一般成功都会返回0, 失败都会返回非0)。
  4. 如果没有成功显示没找到相关信息,否则显示找到了。
  5. 其中"表示转义,在"" 里面还需要显示"号,则需要加上转义符" .

下面运行的例子:

BeautifierPlugin Error: Unable to handle "bash" syntax.

./chapter2.2.sh usage chapter2.2.sh 
Not Found "usage" in chapter2.2.sh
-bash-2.05b$ ./chapter2.2.sh Usage chapter2.2.sh      
echo "Usage: $0 string file";
Found "Usage" in chapter2.2.sh

2 Shell用户变量

2.1 基础

不管系统变量有多少,对于需求来说,总是不够的。用户变量是最常用到的变量,使用也十分简单。

用户定义的变量必须由字母数字及下划线组成,并且变量名的第一个字符不能为数字, 与其它UNIX名字一样,变量名是大小写敏感的. 对于用户变量,用户可按如下方式赋值: BeautifierPlugin Error: Unable to handle "bash" syntax.

  name="Winter"

在引用变量时,需在前面加$符号,用户也可以在变量间进行相互赋值,如: BeautifierPlugin Error: Unable to handle "bash" syntax.

  name="Winter"
  WINTER=$name
  echo "Hello $WINTER !"

输出结果应该很清楚:Hello Winter !

这里需要注意一点:变量和'='之间不要有空格,'='和赋值也不要有空格,否则shell不会认为变量被定义。掌握了基本的使用方法,你可以完全开始你的编程工作了。不过有时候需要未雨绸缪,下面介绍用户变量的一些技巧。

2.2 使用技巧

也可以用变量和其他字符组成新的字,这时可能需要把变量用{}括起,如: BeautifierPlugin Error: Unable to handle "bash" syntax.

 SAT=Satur
 echo Today is ${SAT}day

输出结果是: Today is Saturday

有时候为了避免变量名和别的字符产生混淆,你最好养成习惯把变量名用{}括起来。

对于未赋值的变量, Shell以空值对待, 用户也可以用unset命令清除给变量赋的值.看一个例子: BeautifierPlugin Error: Unable to handle "bash" syntax.

#!/bin/sh
echo "a=$a" ;
a=2
echo "a=$a" ;
unset a
echo "a=$a" ;

先猜猜结果是什么? BeautifierPlugin Error: Unable to handle "bash" syntax.

-bash-2.05b$ ./test.sh 
a=
a=2
a=

如果你懂C++,你应该知道有个变量修饰符"const",用于避免程序一不小心对变量进行修改。在shell中,对于用户变量,你可以使用同样的修饰符"readonly", 如果我把上面的例子修改成这样: BeautifierPlugin Error: Unable to handle "bash" syntax.

#!/bin/sh
echo "a=$a" ;
#下面增加了readonly
readonly a=2    
echo "a=$a" ;
unset a
echo "a=$a" ;

其结果当然会不一样了: BeautifierPlugin Error: Unable to handle "bash" syntax.

-bash-2.05b$ ./test.sh 
a=
a=2
a=2

2.3 shell 中的数组

shell变量中还能设置数组,但是不同的shell版本有不同数组赋值方法,而bourne shell 中不支持数组方式。因此,如果不是十分需要,还是建议你不要使用数组。若你的数据结构十分复杂,必须要使用数组,那么我建议你还是选择别的语言吧,shell不是万能的。

shell有两种赋值方式,第一种是直接用下标赋值: BeautifierPlugin Error: Unable to handle "bash" syntax.

name[0]="Tom"
name[1]="Tomy"
name[2]="John"
...

另一种方式对于不同的shell版本不一样。bash中赋值: BeautifierPlugin Error: Unable to handle "bash" syntax.

#!/usr/local/bin/bash
name=("Tom" "Tomy" "John")
for i in 0  1 2
do
 echo $i:${name[$i]} ;
done;

上面两种赋值方式达到的效果一样。另外,你看见访问数组元素的方法了吗?使用${name[index]}的方式。注意第一行使用的是#!/usr/local/bin/bash, 和以前有些不一样哦。其输出结果是: BeautifierPlugin Error: Unable to handle "bash" syntax.

-bash-2.05b$ ./test.sh    
0:Tom
1:Tomy
2:John

3 shell 环境变量

shell 环境变量是所有shell 程序都会接受的参数。shell程序运行时,都会接收一组变量,这组变量就是环境变量。常用的环境变量:

名称 描述
PATH 命令搜索路径,以冒号为分隔符.注意与DOS下不同的是, 当前目录不在系统路径里
HOME 用户home目录的路径名,是cd命令的默认参数
COLUMNS 定义了命令编辑模式下可使用命令行的长度
EDITOR 默认的行编辑器
VISUAL 默认的可视编辑器
FCEDIT 命令fc使用的编辑器
HISTFILE 命令历史文件
HISTSIZE 命令历史文件中最多可包含的命令条数
HISTFILESIZE 命令历史文件中包含的最大行数
IFS 定义SHELL使用的分隔符
LOGNAME 用户登录名
MAIL 指向一个需要SHELL监视其修改时间的文件.当该文件修改后, SHELL将发消息You hava mail给用户
MAILCHECK SHELL检查MAIL文件的周期,单位是秒
MAILPATH 功能与MAIL类似.但可以用一组文件,以冒号分隔,每个文件后可跟一个问号和一条发向用户的消息
SHELL SHELL的路径名
TERM 终端类型
TMOUT SHELL自动退出的时间,单位为秒,若设为0则禁止SHELL自动退出
PROMPT_COMMAND 指定在主命令提示符前应执行的命令
PS1 主命令提示符
PS2 二级命令提示符,命令执行过程中要求输入数据时用
PS3 select的命令提示符
PS4 调试命令提示符
MANPATH 寻找手册页的路径,以冒号分隔
LD_LIBRARY_PATH 寻找库的路径,以冒号分隔

这些变量,要关注的最多的就是PATH, 其重要性不要我说了吧?

如果你希望把你定义的变量让其他所有的shell程序都能使用,也就是定义新的环境变量。你只要使用export关键词就可以了。例如: BeautifierPlugin Error: Unable to handle "bash" syntax.

export MY_NAME=Winter
export PATH=/home/winter/bin:$PATH

上面的程序中,第一行输出MY_NAME变量,第二行是在环境变量PATH中增加一个路径/home/winter/bin 。如果你希望这些设置在你登陆unix/linux都有效,你需要把他们加入到你的shell启动脚本中, 如果是使用bash BeautifierPlugin Error: Unable to handle "bash" syntax.

~/.bash_profile

其他版本你看一眼就知道了,在你的home目录下,以"."开头的文件,一般都会隐藏起来,你需要使用'ls -al'命令来显示


原文地址:https://www.cnblogs.com/toowang/p/2482827.html