linux sh : user array as function's input or output parameter
发布日期:2021-06-30 22:17:02
浏览次数:2
分类:技术文章
本文共 15260 字,大约阅读时间需要 50 分钟。
前言
看了一段书,讲到了用数组作为脚本函数的入参和出参,正好是我有需求的地方。
前面做的实验,暂时不知道怎么传出多个参数,就每个函数配发了专用的全局变量(有几个出参就配发函数专用的几个全局变量),这样写维护不方便,丑陋。
将前面的一个实验(功能是全的),将全局变量换成数组。 搞了2天,细节蛮多,改的不对,结果不对了。调试了很久。可以用bash -x my.sh, 来调试,也不方便。还是要将基础函数测试过,然后搭积木,可维护性高。如果有错误,用echo来打印调试语句,配合read 暂停程序,来的实在。
如果sh大了,有个几千行,那调试过程就繁琐了。如果有像gdb那样能单步调试脚本的调试器就好了。
# if need pause sh, do below # local c_tmp='' # read -n1 c_tmp
for 循环是依赖IFS的,在for的上面保存旧IFS, 设置新IFS,等for循环结束后,恢复IFS。今天调试时,有一个bug,是由IFS引起的。
实验
# !/bin/bash# @file demo_004.sh# @brief wrap a shell script functin to check user exist, # use array to pass output parameter, not use any global var# run result# --------------------------------------------------------------------------------# | @file demo_004.sh# | @brief wrap a shell script functin to check user exist# | use array to pass output parameter, not use any global var# --------------------------------------------------------------------------------# | check user exist# | 1.0.0.4# | 2018-02-12 14:45# --------------------------------------------------------------------------------# | 2018_02_13_05_13_10# | /bin/bash# | zh_CN.UTF-8# | root# --------------------------------------------------------------------------------# user [root] exist, user home dir = [/root])## user [dev] not exist, but have home dir, user home dir = [/home/dev]## user [user_not_exist] not exist## --------------------------------------------------------------------------------# | END# --------------------------------------------------------------------------------# --------------------------------------------------------------------------------# define macro# --------------------------------------------------------------------------------# run time env is debian7.5PROG_NAME="check user exist"PROG_VER="1.0.0.4"PROG_TIME="2018-02-12 14:45"IND_CHAR=-LINE10=${IND_CHAR}${IND_CHAR}${IND_CHAR}${IND_CHAR}${IND_CHAR}${IND_CHAR}${IND_CHAR}${IND_CHAR}${IND_CHAR}${IND_CHAR}LINE80=${LINE10}${LINE10}${LINE10}${LINE10}${LINE10}${LINE10}${LINE10}${LINE10}WALL_CHAR='|'# --------------------------------------------------------------------------------# global value# --------------------------------------------------------------------------------## err code define#G_ERR_CODE_BASE=0G_ERR_CODE_OK=$(echo "scale=4; $G_ERR_CODE_BASE + 0" | bc)G_ERR_CODE_ERR=$(echo "scale=4; $G_ERR_CODE_BASE + 1" | bc)G_ERR_CODE_USER_NOT_EXIST=$(echo "scale=4; $G_ERR_CODE_BASE + 2" | bc)G_ERR_CODE_USER_NOT_EXIST_BUT_HAVE_HOME_DIR=$(echo "scale=4; $G_ERR_CODE_BASE + 3" | bc)# row info below# games:x:5:60:games:/usr/games:/bin/sh# one row have 7 fields, indicate char is ':'# field 0 is username# field 5 is home dir#g_etc_passwd_row_field_index_user_name=0g_etc_passwd_row_field_index_home_dir=5# --------------------------------------------------------------------------------# init# --------------------------------------------------------------------------------function func_init() { local i_index=0 clear # print 25 empty lines for run result for (( i_index=0; i_index < 25; i_index++ )) do echo done}# --------------------------------------------------------------------------------# uinit# --------------------------------------------------------------------------------function func_uinit() { exit 0}# --------------------------------------------------------------------------------# show title# --------------------------------------------------------------------------------function func_show_title() { echo -e "${LINE80}" echo -e -n "${WALL_CHAR}" echo -e "\t@file\tdemo_004.sh" echo -e -n "${WALL_CHAR}" echo -e "\t@brief\twrap a shell script functin to check user exist" echo -e -n "${WALL_CHAR}" echo -e "\t\tuse array to pass output parameter, not use any global var" echo -e "${LINE80}"}# --------------------------------------------------------------------------------# show tail# --------------------------------------------------------------------------------function func_show_tail() { echo -e "${LINE80}" echo -e -n "${WALL_CHAR}" echo -e "\tEND" echo -e "${LINE80}"}# --------------------------------------------------------------------------------# show os info# --------------------------------------------------------------------------------function func_show_os_info() { local str_date=$(date +%Y_%m_%d_%H_%M_%S) # show time echo -e -n "${WALL_CHAR}" echo -e "\t${str_date}" # show shell echo -e -n "${WALL_CHAR}" echo -e "\t${SHELL}" # show language echo -e -n "${WALL_CHAR}" echo -e "\t${LANG}" # show user echo -e -n "${WALL_CHAR}" echo -e "\t${USER}" echo -e "${LINE80}"}# --------------------------------------------------------------------------------# show prog info# --------------------------------------------------------------------------------function func_show_prog_info() { # show prog name echo -e -n "${WALL_CHAR}" echo -e "\t${PROG_NAME}" # show prog version echo -e -n "${WALL_CHAR}" echo -e "\t${PROG_VER}" # show code modify time echo -e -n "${WALL_CHAR}" echo -e "\t${PROG_TIME}" echo -e "${LINE80}"}# --------------------------------------------------------------------------------# @fn func_show_ary()# @param IN array name# @param IN array self# --------------------------------------------------------------------------------function func_show_ary() { local array_in="" local ary_item="" local i_index=0 local i_index_to_disp=0 array_in=$@ IFS_org=$IFS IFS=$' ' for ary_item in $array_in do # skip $1, this is array name if [ $i_index -ne 0 ] then echo "$1[$i_index_to_disp] = $ary_item" i_index_to_disp=$(echo "scale=4; $i_index_to_disp + 1" | bc) fi i_index=$(echo "scale=4; $i_index + 1" | bc) done IFS=$IFS_org echo}# --------------------------------------------------------------------------------# @fn func_get_ary_by_index()# @brief the all array is {index_obj, ary[0], ary[1], ary[2], ...}# @param IN array index, index base 0, if index is 0, return ary[0], not return index_obj# @param IN array self# @return ary[i]# --------------------------------------------------------------------------------function func_get_ary_by_index() { # ! because need use echo pass output parameter, so don't echo other messages on function or sub function local array_in="" local ary_item="" local i_index=0 local i_index_obj=$1 array_in=$@ i_index_obj=$(echo "scale=4; $i_index_obj + 1" | bc) i_index=0 IFS_org=$IFS IFS=$' ' for ary_item in $array_in do if [ $i_index -eq 0 ] then # $1 is the obj index i_index_obj=$ary_item i_index_obj=$(echo "scale=4; $i_index_obj + 1" | bc) elif [ $i_index -eq $i_index_obj ] then echo "$ary_item" break fi i_index=$(echo "scale=4; $i_index + 1" | bc) done IFS=$IFS_org return 0}# --------------------------------------------------------------------------------# @fn func_get_user_name_and_home_dir_for_one_row_from_etc_passwd# @brief get usrname and homedir from one row from /etc/passwd# @parameter IN, $1, row content# @parameter OUT, array ary_to_return, # ary_to_return[0] = arysize, # ary_to_return[1] is rc, # ary_to_return[2] is username, # ary_to_return[3] = home dir# @return G_ERR_CODE_OK or G_ERR_CODE_ERR# --------------------------------------------------------------------------------function func_get_user_name_and_home_dir_for_one_row_from_etc_passwd() { local ary_to_return local rc=$G_ERR_CODE_ERR local str_user_name="" local str_home_dir="" local str_field="" local IFS_org="" local pos=0 local b_was_get_user_name=false local b_was_get_home_dir=false IFS_org=$IFS IFS=$':' for str_field in $1 do if [ $pos -eq $g_etc_passwd_row_field_index_user_name ] then b_was_get_user_name=true str_user_name=$str_field elif [ $pos -eq $g_etc_passwd_row_field_index_home_dir ] then b_was_get_home_dir=true str_home_dir=$str_field fi pos=$(echo "scale=4; $pos + 1" | bc) # pos++ if [ "$b_was_get_home_dir" = true ] && [ "$b_was_get_home_dir" = true ] then rc=$G_ERR_CODE_OK break fi done IFS=$IFS_org # fill output parameter ary_to_return[0]=3 ary_to_return[1]=$rc ary_to_return[2]=$str_user_name ary_to_return[3]=$str_home_dir echo ${ary_to_return[*]} # this is all array content return $rc}# --------------------------------------------------------------------------------# @fn func_case_gen_ary# @brief gen ary[4] to test# @prarmeter OUT, ary_to_return# ary_to_return[0] = ary size# ary_to_return[1] = return code# ary_to_return[2] = user name# ary_to_return[3] = home dir# @return g_err_code_xx# --------------------------------------------------------------------------------function func_case_gen_ary() { # ! because need use echo pass output parameter, so don't echo other messages on function or sub function local rc=$G_ERR_CODE_USER_NOT_EXIST_BUT_HAVE_HOME_DIR local ary_to_return ary_to_return[0]=3 ary_to_return[1]=$rc ary_to_return[2]="user_name" ary_to_return[3]="user_home_dir" echo ${ary_to_return[*]} # this is all array content return $rc}# --------------------------------------------------------------------------------# @fn func_is_user_exist# @brief is user exist# @parameter IN, username# @prarmeter OUT, ary_to_return# ary_to_return[0] = ary size# ary_to_return[1] = return code# ary_to_return[2] = user name# ary_to_return[3] = home dir# @return g_err_code_xx# --------------------------------------------------------------------------------function func_is_user_exist() { # ! because need use echo pass output parameter, so don't echo other messages on function or sub function local ary_to_return local rc=$G_ERR_CODE_ERR local str_user_name="" local str_user_home="" local str_user_name_rv="" local IFS_org="" local str_row_content="" local str_user_home_rv="" local rc_tmp_ary local rc_tmp=0 # user name str_user_name=$1 # user home str_user_home="/home/${str_user_name}" IFS_org=$IFS IFS=$'\n' for str_row_content in $(cat "/etc/passwd") do rc_tmp_ary=$(func_get_user_name_and_home_dir_for_one_row_from_etc_passwd $str_row_content) # rc_tmp_ary = 4 0 speech-dispatcher /var/run/speech-dispatcher rc_tmp=$? str_user_name_rv=$(func_get_ary_by_index 2 $rc_tmp_ary) str_user_home_rv=$(func_get_ary_by_index 3 $rc_tmp_ary) if [ $rc_tmp -eq $G_ERR_CODE_ERR ] then continue elif [ "$str_user_name" = "$str_user_name_rv" ] then # ok : on rc_tmp_ary, can get username and homedir rc=$G_ERR_CODE_OK break; fi done IFS=$IFS_org if [ $rc -eq $G_ERR_CODE_OK ] then # find user in /etc/passwd # set rc, fill ary and echo ary, then to return ary_to_return[0]=3 # parameter counter(3 = $G_ERR_CODE_OK + user_name + user_home_dir) ary_to_return[1]=$rc # reture code ary_to_return[2]=$str_user_name_rv # user name ary_to_return[3]=$str_user_home_rv # user home dir echo ${ary_to_return[*]} # this is all array content return $rc fi # if user name not in /etc/passwd, try to find is the user have home dir ? # before opt a file, please check is file exist. if file is dir, do check also # do check can guard some error message on opt file if ! [ -d $str_user_home ] then rc=$G_ERR_CODE_USER_NOT_EXIST # fill output parameter ary_to_return[0]=3 ary_to_return[1]=$rc ary_to_return[2]=$str_user_name ary_to_return[3]="" echo ${ary_to_return[*]} return $rc fi # ls -d xx # only list dir by give str_user_name_rv=$str_user_name str_user_home_rv=$(ls -d $str_user_home) # e.g. return /home/root rc_tmp=$? #e.g. return 0, 1, or other int value # if dir not exist, rc_tmp = 2 # rc_tmp is number, cmpare use -eq if [ 0 -eq $rc_tmp ] then str_user_home_rv=$str_user_home rc=${G_ERR_CODE_USER_NOT_EXIST_BUT_HAVE_HOME_DIR} else str_user_home_rv="" rc=${G_ERR_CODE_USER_NOT_EXIST} fi # fill ary and echo ary, set rc to return ary_to_return[0]=3 ary_to_return[1]=$rc ary_to_return[2]=$str_user_name_rv ary_to_return[3]=$str_user_home_rv echo ${ary_to_return[*]} # this is all array content return $rc}# --------------------------------------------------------------------------------# fuc_show_user_info# --------------------------------------------------------------------------------function fuc_show_user_info() { local ary_to_return local rc=0 local i_index=0 local ary_val="" local str_user_name="" local str_user_home="" # $1 is user name ary_to_return=$(func_is_user_exist $1) rc=$? # func_show_ary "ary_to_return" $ary_to_return if [ $rc -eq $G_ERR_CODE_OK ] then str_user_name=$(func_get_ary_by_index 2 $ary_to_return) str_user_home=$(func_get_ary_by_index 3 $ary_to_return) echo "user [$str_user_name] exist, user home dir = [$str_user_home])" elif [ $rc -eq $G_ERR_CODE_USER_NOT_EXIST_BUT_HAVE_HOME_DIR ] then str_user_name=$(func_get_ary_by_index 2 $ary_to_return) str_user_home=$(func_get_ary_by_index 3 $ary_to_return) echo "user [$str_user_name] not exist, but have home dir, user home dir = [$str_user_home]" elif [ $rc -eq $G_ERR_CODE_USER_NOT_EXIST ] then str_user_name=$(func_get_ary_by_index 2 $ary_to_return) echo "user [$str_user_name] not exist" else echo "unknow return code, please contact admin" fi echo}# --------------------------------------------------------------------------------# do task# --------------------------------------------------------------------------------function func_do_task() { # test user exist and have home dir fuc_show_user_info "root" # user not exist, but have home dir fuc_show_user_info "dev" # user not exist and have not home dir fuc_show_user_info "user_not_exist"}# --------------------------------------------------------------------------------# save some test case# --------------------------------------------------------------------------------function func_test_case() { # test : gen ary ary_to_return=$(func_case_gen_ary) rc=$? # test : show ary func_show_ary "ary_to_return" $ary_to_return # test : func_get_ary_by_index, index base 0 str_rv=$(func_get_ary_by_index 0 $ary_to_return) echo "str_rv = $str_rv" func_get_ary_by_index 1 $ary_to_return func_get_ary_by_index 2 $ary_to_return ary_element_3=$(func_get_ary_by_index 3 $ary_to_return) echo "ary_to_return[3] = $ary_element_3"}# --------------------------------------------------------------------------------# main shell script# --------------------------------------------------------------------------------func_initfunc_show_titlefunc_show_prog_infofunc_show_os_info# func_test_casefunc_do_taskfunc_show_tailfunc_uinit
转载地址:https://lostspeed.blog.csdn.net/article/details/79322236 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
感谢大佬
[***.8.128.20]2024年04月10日 19时42分35秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
how2heap-fastbin_dup_consolidate
2019-04-30
orw_shellcode_模板
2019-04-30
[fmt+shellcode]string
2019-04-30
fmt在bss段(neepusec_easy_format)
2019-04-30
python 函数式编程
2019-04-30
python编码
2019-04-30
redis cli
2019-04-30
java 解析json
2019-04-30
java http请求
2019-04-30
tensorflow 数据格式
2019-04-30
tf rnn layer
2019-04-30
tf input layer
2019-04-30
tf model create
2019-04-30
tf dense layer两种创建方式的对比和numpy实现
2019-04-30
tf initializer
2019-04-30
tf 从RNN到BERT
2019-04-30
tf keras SimpleRNN源码解析
2019-04-30
tf keras Dense源码解析
2019-04-30
tf rnn输入输出的维度和权重的维度
2019-04-30
检验是否服从同一分布
2019-04-30