스 크 립 트 입력 처리 - 파라미터 처리
60628 단어 shell
매개 변수 처리
일반적으로 Shell 스 크 립 트 를 더욱 유연 하고 광범 위 하 게 응용 하기 위해 다양한 행동 을 하기 위해 스 크 립 트 를 작성 할 때 명령 행 인 자 를 받 습 니 다. 명령 행 인 자 를 통 해 스 크 립 트 의 변 수 를 지정 하여 스 크 립 트 가 서로 다른 동작 을 수행 하도록 합 니 다.
case 구문 처리 명령 행 매개 변수
스 크 립 트 가 명령 행 인자 만 받 고 매개 변수 에 따라 다른 행동 을 할 때 보통 case 문 구 를 사용 합 니 다.
nginx 시작 스 크 립 트 작성
스 크 립 트 파일 nginx. sh 를 작성 합 니 다.(전제 시 소스 코드 는 nginx 서 비 스 를 설 치 했 고 소스 코드 는 nginx 서 비 스 를 설치 하여 service 시작 스 크 립 트 를 제공 하지 않 습 니 다)
[root@nginx mnt]# cat nginx.sh
# chkconfig: - 85 15
# description: nginx is a World Wide Web server. It is used to serve
#加载function库,使用function种的status、killproc等函数
. /etc/rc.d/init.d/functions
#加载网络配置文件
. /etc/sysconfig/network
#检查网络是否启动,如果不能直接退出
[ "$NETWORKING" = "no" ] && exit 0
#定义变量
nginx="/usr/sbin/nginx"
prog=$(basename $nginx)
NGINX_CONF_FILE="/etc/nginx/nginx.conf"
lockfile=/var/lock/subsys/nginx
#如果有该文件,加载进来
test -f "/etc/sysconfig/nginx" && . /etc/sysconfig/nginx
#测试nginx主配置文件是否有语法错误
configtest() {
$nginx -t
}
#启动函数
start() {
#检查关键文件是否存在,二进制脚本和配置文件
[ -x $nginx ] || exit 5
[ -f $NGINX_CONF_FILE ] || exit 6
#创建pid存放目录,如果该目录不存在才创建
mkdir -p /var/run/nginx
#使用daemon函数便利nginx主配置文件,并启动
echo -n $"Starting $prog:"
daemon $nginx -c $NGINX_CONF_FILE
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
#停止函数
echo $"Stopping $prog: "
killproc $prog -QUIT
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
#重启函数
configtest || return $?
stop
sleep 3
start
}
reload() {
#不重启情况下,重新加载配置文件
configtest || return $?
echo -n $"Reloading $prog: "
killproc $nginx -HUP
RETVAL=$?
echo
}
#强制重启
force_reload() {
restart
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
reload)
reload
;;
status)
status $prog
[ $? -eq 0 ] && echo -n `configtest`
;;
force_reload)
restart
;;
*)
echo "Usage:$prog {start|stop|restart|reload|force_reload|status}"
exit 1
;;
esac
주의:
스 크 립 트 service 를 추가 하려 면 다음 두 줄
# chkconfig: - 85 15
# description: nginx is a World Wide Web server. It is used to serve
을 포함해 야 합 니 다.linux 내장 함수 status 와 killproc 를 사 용 했 습 니 다.
서비스 목록 에 추가
[root@nginx mnt]# cp nginx.sh /etc/rc.d/init.d/nginx
[root@nginx mnt]# chmod +x /etc/rc.d/init.d/nginx
[root@nginx mnt]# chkconfig --add nginx
테스트 [root@nginx mnt]# service nginx status
nginx.service - SYSV: nginx is a World Wide Web server. It is used to serve
Loaded: loaded (/etc/rc.d/init.d/nginx)
Active: active (running) since Sun 2018-07-08 10:55:29 CST; 6min ago
Process: 4781 ExecStop=/etc/rc.d/init.d/nginx stop (code=exited, status=0/SUCCESS)
Process: 4803 ExecStart=/etc/rc.d/init.d/nginx start (code=exited, status=0/SUCCESS)
CGroup: /system.slice/nginx.service
├─4808 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
└─4810 nginx: worker process
Jul 08 10:55:29 nginx systemd[1]: Starting SYSV: nginx is a World Wide Web server. It is...e...
Jul 08 10:55:29 nginx nginx[4803]: Starting nginx:[ OK ]
Jul 08 10:55:29 nginx systemd[1]: Started SYSV: nginx is a World Wide Web server. It is ...rve.
Hint: Some lines were ellipsized, use -l to show in full.
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx mnt]# service nginx restart
Restarting nginx (via systemctl): [ OK ]
[root@nginx mnt]# service nginx we
Usage:nginx {start|stop|restart|reload|force_reload|status}
status 함수# 检测一个二进制可运行程序是否运行:
# 使用方法:
status [-p pidfile] {program}
status() {
local base pid pid_file=
# Test syntax. # 测试调用该函数时的参数格式。
if [ "$#" = 0 ] ; then
echo $"Usage: status [-p pidfile] {program}"
# 如果调用该函数没有给一个参数的话就显示:该函数的使用方法,然后直
#接退出。退出状态码:1
return 1
fi
if [ "$1" = "-p" ]; then
pid_file=$2
shift 2
fi
base=${1##*/} # 使用$base 记录二进制可运行程序的文件名。
# First try "pidof"
__pids_var_run "$1" "$pid_file"
# 调用函数:__pids_var_run 来检测二进制程序的运行状态。
RC=$?
if [ -z "$pid_file" -a -z "$pid" ]; then
# 如果调用 status时,没有传递pidfile文件,并且没有检测到PID号
pid="$(__pids_pidof "$1")"
# 因为有些二进制可运行程序,是不会把PID写到
# /var/run/$base.pid文件当中的。就调用函数__pids_pidof来查找PID号
fi
####################################################################
if [ -n "$pid" ]; then
# 如果查到二进制运行程序的PID号,就代表该该二进制程序是运行的。
echo $"${base} (pid $pid) is running..."
return 0
fi
case "$RC" in
# 根据函数:__pids_var_run返回的状态码,来判断二进制程序的运行状态。
0)
echo $"${base} (pid $pid) is running..."
return 0
;;
1)
echo $"${base} dead but pid file exists"
# 如果函数:__pids_var_run返回的状态码是:1 ,的话....
return 1
;;
esac
#####################################################################
# See if /var/lock/subsys/${base} exists # ***锁文件。
if [ -f /var/lock/subsys/${base} ]; then
echo $"${base} dead but subsys locked"
return 2
fi
echo $"${base} is stopped"
return 3
killproc 함수
# 该函数的作用是关闭进程的.
# 用法:
# killproc [-p pidfile] [-d delay] [-signal]
# -p: 指定进程的pid文件,一般在/var/run/xxx.pid
# -d: 指定延迟多长时间就强度关闭进程
# -signal: 关闭进程的信号
# A function to stop a program.
killproc() {
local RC killlevel= base pid pid_file= delay
# 定义局部变量,只在函数体内有效。
RC=0; delay=3 # 默认延迟3秒,不能正常关闭就强制关闭
# Test syntax. # 判断用户调用该函数时,给的参数格式。并使用变量记录下来
if [ "$#" -eq 0 ]; then
echo $"Usage: killproc [-p pidfile] [ -d delay] {program} [-signal]“
# 如果调用该函数时,不使用任何参数的话将给用户输出使用该函数的使用方法。
return 1 # 退出该函数。
fi
if [ "$1" = "-p" ]; then
# 如果参数1,是字符 -p 的话,那么用户输入的第二个参数就是:
# 程序的pid_file文件。通常是/var/run/XXX.pid
pid_file=$2
shift 2
fi
if [ "$1" = "-d" ]; then
delay=$2
# 记录的参数的作用是用来。如果进程在正常情况下不能关闭,
# 延迟多长时间就向该进程发送SIGKILL信号强制关闭。
shift 2
fi
# check for second arg to be kill level
# 检查用户是否指定函数关闭进程时,所使用的信号。
[ -n "${2:-}" ] && killlevel=$2
# Save basename. # 保存进程的二进制运行文件的。
base=${1##*/} # 参数替换,把程序的二进制文件的路径名***掉。
####################################################################
# 查找可运行二进制程序的进程号PID 部分
# Find pid.
__pids_var_run "$1" "$pid_file"
#调用 函数:__pids_var_run 来检查用户指定的程序的进程号。
# 该函数会使用一个变量:PID记录程序的进程号的。
if [ -z "$pid_file" -a -z "$pid" ]; then
# 如果pidfile文件不存在,并且找不到进程的pid号。
# 就使用该方法查找该程序$base的PID号。
pid="$(__pids_pidof "$1")"
fi
#####################################################################
# Kill it.
# 找到二进制可运行程序的进程号,是如果关闭进程的
if [ -n "$pid" ] ; then
# 如果$PID 不为空,证明进程运行的。就执行 then 后的内容
[ "$BOOTUP" = "verbose" -a -z "${LSB:-}" ] && echo -n "$base "
if [ -z "$killlevel" ] ; then
#如果用户没有指定函数要使用关闭进程的信号的话,就执行 then后的内容
if checkpid $pid 2>&1; then
# 调用函数:checkpid 来判断进程号为:$PID的进程是否
#运行。其实 checkpid是判断$PID,如果伪目录/proc
#下是否有一个目录名和$PID相同
# TERM first, then KILL if not dead
kill -TERM $pid >/dev/null 2>&1
# 给进程$PID发送 -15信号。等待进程关闭资源后,
# 再杀死该进程。
usleep 100000 #等待100000 微秒
if checkpid $pid && sleep 1 &&
#再使用函数checkpid检查,如果进程还运行的话,
#再等待1秒,
checkpid $pid && sleep $delay &&
#再使用函数checkpid检查,如果进程还运行的话,
#就使用用户给的延迟时间,再等待
checkpid $pid ; then
#在用户给的延时时间到了,再次使用函数
#checkpid检查,如果进程还是运行的
# 话,就强制关闭。
kill -KILL $pid >/dev/null 2>&1
# 给进程$PID发送 -9 信号,强制关闭该进程。
usleep 100000
fi
fi
checkpid $pid # 再次确认下,进程$PID是否是关闭的。
RC=$?
# 记录函数checkpid的返回结果。
# 如果是:0 的话就代表关闭进程$PID成功。
[ "$RC" -eq 0 ] && failure $"$base shutdown" || success $"$base shutdown"
# 判断函数checkpid的返回值,给用户输出进程是否关闭成功的信 RC=$((! $RC))
# 对变量RC进行,非操作,避免下面使用该变量时,判断有误。
# use specified level only
#调用函数:killproc时传递有关闭进程的信号就执行else 后的程序
else # 如果用户给函数killproc 传递了关闭进程所使用的信号,
#就执行else后的代码
# 作用想要通知进程重读配置文件时, 可以传递一个 -HUP 信号给进程。
if checkpid $pid; then #使用函数checkpid检查,进程$PID是否运行的,
kill $killlevel $pid >/dev/null 2>&1
#使用用户传递关闭进程的信号来关闭进程$PID
RC=$? #记录函数checkpid的返回结果。
[ "$RC" eq 0 ] && success $"$base $killlevel" || failure $"$base $killlevel"
# 根据$RC判断进程$PID是否关闭成功
elif [ -n "${LSB:-}" ]; then
RC=7 # Program is not running
fi
fi
###########################找不到二进制可运行程序的进程号
else
if [ -n "${LSB:-}" -a -n "$killlevel" ]; then
RC=7 # Program is not running
else
failure $"$base shutdown"
RC=0
fi
fi
# Remove pid file if any.
if [ -z "$killlevel" ]; then
rm -f "${pid_file:-/var/run/$base.pid}"
fi
return $RC
}
shift 명령 처리 명령 행 인자
명령 행 에 여러 개의 인자 가 있 을 때 shift 명령 을 사용 하여 한 변수 에서 여러 명령 행 인 자 를 하나씩 가 져 올 수 있 습 니 다.
shift 시 Bash 의 내부 명령 은 전 달 된 매개 변 수 를 왼쪽으로 이동 하 는 데 사 용 됩 니 다.문법 은 다음 과 같다.
shift [n]
그 중에서 n 은 '\#' 보다 작은 비 마이너스 정수 여야 합 니 다.n 이 0 이면 위치 매개 변 수 는 변 하지 않 습 니 다.n 이 지정 되 지 않 으 면 기본 값 은 1 입 니 다. n 이 $\# 보다 크 거나 0 보다 작 으 면 이 명령 의 반환 상태 코드 는 1 보다 크 고 그렇지 않 으 면 0 입 니 다.
예 를 들 어 shift 1 명령 을 사용 하면 위치 매개 변 수 는 이렇게 이동 합 니 다.
$1
$2
...
$n-1
원래 의 $1 을 잃 어 버 립 니 다.$1 이 분실 되 었 기 때문에 특수 변수 $\# 의 값 도 변 경 됩 니 다.
예:
#如果命令行参数个数不为0,则继续while循环,否则退出循环
while [ $# -ne 0 ]
#如果$1的值不为空,则进入while循环
#while test -n "$1"
do
#打印$1的值,和特殊变量$#的值
echo "Current Parameter \$1: $1,Remaining $#."
#然后可以将$1传递到别的函数进行其他操作
#Pass $1 to some bash function ir do whatever
#左移一位
shift
done
스 크 립 트 결과 실행:
[root@rs1 shift]# bash getCml.sh fsx coco tom kobe
Current Parameter $1: fsx,Remaining 4.
Current Parameter $1: coco,Remaining 3.
Current Parameter $1: tom,Remaining 2.
Current Parameter $1: kobe,Remaining 1.
예 를 들 어 실 행 된 shift 5 시 전달 할 수 있 는 매개 변수 개 수 는 5 로 나 눌 수 없습니다. 예 를 들 어 7 개의 매개 변 수 를 전달 할 때 왼쪽 에서 한 번 이동 한 후에 여섯 번 째 매개 변수 ($6) 에 도착 하고 나머지 두 개의 매개 변수 ($\# = 2) 는 계속 실행 되 지 않 지만 $1 이 비어 있 지 않 고 $\# 의 값 이 0 이 되 지 않 으 면 while 가 무한 순환 할 수 있 습 니 다.
이 문 제 를 해결 하기 위해 서 는 shift 명령 의 종료 상 태 를 사용 할 수 있 습 니 다.shift 명령 을 통 해 변 수 를 $?값 이 0 인지 가 져 오 면 shift 명령 이 실 행 될 지 여 부 를 판단 할 수 있 습 니 다.하면, 만약, 만약...0 이 아니면 집행 을 중지 합 니 다.
[root@rs1 shift]# cat shift5.sh
#如果命令行参数个数不为0,则继续while循环,否则退出循环
while test -n "$1"
do
#打印$1的值,和特殊变量$#的值
echo "Current Parameter \$1: $1,Remaining $#."
#然后可以将$1传递到别的函数进行其他操作
#Pass $1 to some bash function ir do whatever
#左移五位
shift 5
#如果上一条命令执行结果不为0,则执行if语句
if [ $? -ne 0 ]
then
#终止执行
break
fi
done
스 크 립 트 실행:
[root@rs1 shift]# bash -x shift5.sh a b c d e f g
+ test -n a
+ echo 'Current Parameter $1: a,Remaining 7.'
Current Parameter $1: a,Remaining 7.
+ shift 5
+ '[' 0 -ne 0 ']' //此处$?为0,则不进入if语句内部
+ test -n f
+ echo 'Current Parameter $1: f,Remaining 2.'
Current Parameter $1: f,Remaining 2.
+ shift 5
+ '[' 1 -ne 0 ']' //此处#?为1,则进入if语句内部,执行break
+ breakS
for 순환 으로 여러 매개 변 수 를 읽 기
명령 행 매개 변수 개수 가 너무 많 을 때 shift 명령 을 사용 하 는 것 외 에 for 를 사용 하여 모든 명령 행 매개 변 수 를 하나씩 순환 할 수 있 습 니 다.
예:
[root@rs1 for]# cat listarg.sh
#定义变量E_BADARGS
E_BADARGS=65
#如果特殊变量$1为空,则打印脚本使用方法,并以退出码65退出脚本
if [ ! -n "$1" ]
then
#打印脚本的使用方法到标准输出
echo "Usage: `basename $0` argument1 argument2 ..."
#退出脚本,状态码为65
exit $E_BADARGS
fi
#定义变量index
index=1
#打印双引号种的内容到标准输出
echo "Listing args wiht \"$*\":"
#使用for循环遍历整个特殊变量$*的值
for arg in "$*"
do
#打印输出变量index和arg的值及相应内容到标准输出
echo "Arg $index = $arg"
#将index值加一
let index+=1
done
#重新将变量index值设置为1
index=1
#打印双引号内容到标准输出
echo "Listing args with \"$@\":"
#使用for循环遍历特殊变量$@的值
for arg in "$@"
do
#打印输出变量index和arg的值及相应内容到标准输出
echo "Arg $index = $arg"
#将变量index值加一
let index+=1
done
스 크 립 트 실행:
[root@rs1 for]# bash listarg.sh fsx coco kobe
Listing args wiht "$*": //如果$*加了"",则其中内容会被当成一个字符串。$*不加""则会由IFS隔开,被认为成多个字符串
Arg 1 = fsx coco kobe
Listing args with "$@":
Arg 1 = fsx
Arg 2 = coco
Arg 3 = kobe
메모: "$*"와 $* 의 차이 점 - $* 에 더 블 따옴표, 즉 "$"를 추가 하면 모든 위치 매개 변 수 를 포함 하 는 값 의 단일 문자열 로 확 장 됩 니 다. for 순환 은 한 번 만 교체 합 니 다.
스 크 립 트 이름 읽 기
특수 변수 $0 의 값 은 현재 Shell 스 크 립 트 의 이름 입 니 다. $0 으로 스 크 립 트 이름 을 읽 을 수 있 습 니 다.
Shell 을 작성 할 때 스 크 립 트 를 더욱 엄밀 하 게 만 들 고 스 크 립 트 가 실 행 될 때 발생 할 수 있 는 이상 한 오 류 를 줄 이기 위해 스 크 립 트 를 시작 할 때 스 크 립 트 와 관련 된 환경 이나 변 수 를 만들어 서 코드 를 검사 해 야 합 니 다.예 를 들 어 지정 한 스 크 립 트 의 명령 행 매개 변수 개수 가 스 크 립 트 정의 에 부합 되 는 지 확인 하고 일치 하지 않 으 면 스 크 립 트 의 명령 행 매개 변수 사용 방법 에 대한 정 보 를 표준 출력 으로 직접 인쇄 하고 스 크 립 트 를 종료 합 니 다.
예:
[root@rs1 for]# cat check.sh
#定义脚本参数个数
ARGS=3
#如果指定给脚本的参数个数不为3,则进入if语句
if test $# -ne "$ARGS"
then
#打印使用方法
echo "Usage:`basename $0` param1 param2 param3."
#退出脚本
exit 2
fi
스 크 립 트 실행:
[root@rs1 for]# bash check.sh //参数个数不对
Usage:check.sh param1 param2 param3.
[root@rs1 for]# bash check.sh 1 2 3 //参数个数正确
[root@rs1 for]# bash check.sh 1 2 3 4 //参数个数不对
Usage:check.sh param1 param2 param3.
테스트 명령 행 매개 변수
스 크 립 트 를 더욱 엄밀 하 게 하기 위해 서 는 실행 중 매개 변수 오류 로 인 한 이상 을 방지 하기 위해 서 는 일반적으로 매개 변수 값 을 검사 합 니 다. 예 를 들 어 지정 한 매개 변수 일 때 파일 이나 디 렉 터 리 가 존재 하 는 지, 실행 가능 한 지 등 을 검사 합 니 다.
예:
[root@rs1 for]# cat test2.sh
#定义脚本的参数个数
ARGS=2
if test $# -ne "$ARGS"
then
echo "Usage: `basename $0` param1 filename"
exit 2
fi
#将第一个命令行参数赋值给变量varStr
varStr=$1
#如果$2存在,则执行if语句,否则执行else语句
if [ -f "$2" ]
then
echo "$0 I Like You But Just Like You." >> $2
cat "$2"
else
echo "File \"$2\" does not exist."
exit 3
fi
스 크 립 트 실행:
[root@rs1 for]# bash test2.sh //没有参数,提示usage
Usage: test2.sh param1 filename
[root@rs1 for]# bash test2.sh 1 //只有一个参数,提示usage
Usage: test2.sh param1 filename
[root@rs1 for]# bash test2.sh 1 2 //有两个参数,但是第二个文件不存在,提示文件不存在
File "2" does not exist.
[root@rs1 for]# touch 2 //创建了一个文件,文件名为2
[root@rs1 for]# bash test2.sh 1 2 //执行没有问题
test2.sh I Like You But Just Like You.
[root@rs1 for]# cat 2
test2.sh I Like You But Just Like You.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
ZSH에서 물고기까지ZSH는 수년 동안 내 기본 셸이었습니다. 이제 몇 달 동안 사용하면서 ZSH 구성에 대해 몇 가지 사항을 발견했습니다. 우리는 을 제공하는 시스템과 더 빨리 상호 작용하는 경향이 있습니다. 내.zshrc 구성에는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.