【shell(man sh)】
vim name.sh
----------------
#! /bin/sh
#写命令
----------------
执行shell的方法
1 /bin/sh ./name.sh
sh ./name.sh
2 先赋给+x权限
chmod +x script.sh
再直接执行
./name.sh
父进程bash -> 子进程sh -> Shebang解释器,把name.sh的代码段替换当前进程的代码段,从_start开始执行->一直读到EOF返回bash等待用户输入
以上工作相当于(cd ~;ls) fork出子进程执行,并不改变交互式shell
???? 如果执行source ./name.sh或者. ./name.sh就相当于直接在交互式shell中执行cd ~;ls
显示当前shell 的environment :
printenv
-----------------------------------------
调试脚本的参数
-n noexec不执行,用于检查错误
-v 打印到标准错误输出
-x 打印每一条执行结果
法一,调用时:
$ sh -x ./script.sh
法二,写在脚本开头中:
#! /bin/sh -x
法三,脚本中用
set -x #启用x参数
set +x #禁用x参数
------------------------------------------
【变量】
显示当前shell中所有变量
set
定义
VARNAME=value
本地shell导出为环境shell
exprot VARNAME[=value]
exprot VARNAME
取消变量
unset VARNAME
打印【变量的取值总是放在"${var}"之中】
echo "${VARNAME}"
echo "$VARNAME" #可能会引起歧义
通配符,打开文件时可以使用
* >=0 个
? 1个
[abc] a或b或c
[a-dX] Matches any character that is either a, b, c, d or X.
命令代换
DATE="`date`"
DATE="$(date)"
算数代换
VAR=45
echo "$(($VAR + 3))"
\取字面值 \$SHELL \\ \" \`
在shell中 touch \(回车)
>-filename
"带有转义符的字符串"
'不带有转义符的字符串'
===========【启动shell】================
【交互式shell】
通过telnet\ssh登录启动,--login参数启动(交互式)登录shell,(也即是其他shell的父shell)
所有用户都执行 /etc/profile
当前用户执行 先~/.bash_profile
先~/.bash_login
如果没有bash_开头的脚本则执行~/.profile(文件中可以覆盖profile中的全局设置)
图形界面的terminal(子),在登录shell(父)再开启一个bash(子),得到交互非登录shell(子shell)
自动执行~/.bashrc
(所以它在terminal和字符终端shell中都起作用,一般设置本地变量,函数,alias)
父shell的环境变量可以带到子shell,但是本地变量、函数、alias等不能
------------------------------------------------------
【非交互式shell】
执行脚本fork出的子shell,环境变量是BASH_ENV
if [-n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
$BASH_ENV非空则source启动它
【sh启动】
交互式:/etc/profile ~/.profile 只启动这两个
if [-n "$ENV"];then . "$ENV"; fi
非交互式:不执行启动脚本
如运行以#! /binsh开头的shell脚本
==================【条件】=========================
通过man [ 查看完整版
[ -d DIR ] 文件夹存在
[ -f FILE ] 文件存在
[ -z STRING ]长度为zero
[ -n STRING ]长度not zero
[ STRING1 = STRING2 ]
[ STRING1 != STRING2 ]
-eq equal =
-ne not qual !=
-lt less than <
-le less than or equal <=
-gt grater than >
-ge grater than or equal >=
-a 与and
-o 或or
! 非
===========【flow control】========================
if list
then list
[ elif list
then list ] ...
[ else list ]
fi
while list
do list
done
#限定循环次数
#COUNTER=1
#while [ "$COUNTER" -lt 10 ]
#do
# ...
# COUNTER=$(($COUNTER+1))
#done
for variable [ in [ word ... ] ]
do list
done
# word缺省则相当于$@(连接所有参数)
break [ num ]
continue [ num ]
case word in
[(]pattern) list ;;
...
esac
#必须以;;结尾,只执行匹配的条件不会go through
#default 可以用 *) list ;; 来写
#以上每个行都是一个命令,如果想把下一行拼接在上一行需要用;分隔
#如if [$VAR -eq 3]; then list
sh中0为真,1为假
: 永远得到true
也可以用/bin/true /bin/false得到0,1返回值
(list)
or
{ list; } 一定以;结尾
{ printf " hello " ; printf " world\n" ; } > greeting
&&成功了往右走
||成功了就短路
================ 【Special Parameters】=============
A special parameter is a parameter denoted by one of the following special characters. The value of the parameter is listed
next to its character.
* Expands to the positional parameters, starting from one. When the expansion occurs within a double-quoted string
it expands to a single field with the value of each parameter separated by the first character of the IFS vari‐
able, or by a ⟨space⟩ if IFS is unset.
@ Expands to the positional parameters, starting from one. When the expansion occurs within double-quotes, each
positional parameter expands as a separate argument. If there are no positional parameters, the expansion of @
generates zero arguments, even when @ is double-quoted. What this basically means, for example, is if $1 is
“abc” and $2 is “def ghi”, then "$@" expands to the two arguments:
"abc" "def ghi"
# Expands to the number of positional parameters.
? Expands to the exit status of the most recent pipeline.
- (Hyphen.) Expands to the current option flags (the single-letter option names concatenated into a string) as specified on
invocation, by the set builtin command, or implicitly by the shell.
{content}nbsp; Expands to the process ID of the invoked shell. A subshell retains the same value of $ as its parent.
! Expands to the process ID of the most recent background command executed from the current shell. For a pipeline,
the process ID is that of the last command in the pipeline.
0 (Zero.) Expands to the name of the shell or shell script.
-------------------------------------------------
$? 得到上一条命令的返回值
$0 第0个参数(文件名)同c的arcv[0]
$1 第一个参数
$# 除了文件名以外的参数个数 同c的argc-1
shift 3 除了文件名外的参数左移3个,前三个丢弃
============================================================================================
read YES_OR_NO #读取用户输入
$YES_OR_NO #之后可以调用输入的值
退出
exit 0
exit 1
======================【函数】===========================
fun()
{
echo hello
echo $@
return
}
#()括号内不写任何
#可以单纯return也可以return 1 相当于exit status,可以在调用后通过$?获取
fun you he and I
#调用的时候不加(),可以传入任意参数,到时候根据$1 $2...调用
echo fun