龙岗企业网站建设,做静态网站的参考文献,网站开发用什么配置电脑,广州网站建设公司推荐什么是shell脚本
当命令或者程序语句写在文件中#xff0c;我们执行文件#xff0c;读取其中的代码#xff0c;这个程序就称之为shell脚本。 有了shell脚本肯定是要有对应的解释器了#xff0c;常见的shell脚本解释器有sh、python、perl、tcl、php、ruby等。一般这种使用文…什么是shell脚本
当命令或者程序语句写在文件中我们执行文件读取其中的代码这个程序就称之为shell脚本。 有了shell脚本肯定是要有对应的解释器了常见的shell脚本解释器有sh、python、perl、tcl、php、ruby等。一般这种使用文件方式来执行sh命令的方式被称为非交互方式。
Windows中存在的*.bat批处理脚本。Linux中常用*.sh脚本文件。
shell脚本规则
在Linux系统中shell脚本或者称之为bash shell程序通常都是vim编辑有Linux命令、bash shell指令、逻辑控制语句和注释信息组成。 google bash编程规范链接
1.使用.sh这样特定语言后缀作为扩展名可以快速识别文件。2.set可以设置shell的选项。SUID(Set User ID)和SGID(Set Group ID)在shell脚本中是被禁止的如果你需要较高权限的访问请使用sudo。3.建议使用STDERR打印错误信息。
err() {echo [$(date %Y-%m-%dT%H:%M:%S%z)]: $ 2
}if ! do_something; thenerr Unable to do_somethingexit ${E_DID_NOTHING}
fi4.文件头指定脚本解释器这里是用#!/bin/bash做解释器的。
#!/bin/bash
#
# Perform hot backups of Oracle databases.5.函数注释应该包括 函数的描述全局变量的使用和修改使用的参数说明返回值而不是上一条命令运行后默认的退出状态 例如
#!/bin/bash
#
# Perform hot backups of Oracle databases.export PATH/usr/xpg4/bin:/usr/bin:/opt/csw/bin:/opt/goog/bin#######################################
# Cleanup files from the backup dir
# Globals:
# BACKUP_DIR
# ORACLE_SID
# Arguments:
# None
# Returns:
# None
#######################################
cleanup() {...
}
6.TODO注释应该包含全部大写的字符串TODO接着是括号中你的用户名。冒号是可选的。最好在TODO条目之后加上 bug或者ticket 的序号。
# TODO(mrmonkey): Handle the unlikely edge cases (bug ####)7.缩进一般使用两个空格没有制表符。8.行的长度和长字符串最大长度为80个字符。 使用下述两种方式规避长字符串
# DO use here documents
cat END;
I am an exceptionally long
string.
END# Embedded newlines are ok too
long_stringI am an exceptionallylong string.9.管道尽量写在一行否则应该将整个管道操作分割成每行一个管段管道操作的下一部分应该将管道符放在新行并且缩进2个空格。这适用于使用管道符’|’的合并命令链以及使用’||’和’’的逻辑运算链。
# All fits on one line
command1 | command2# Long commands
command1 \| command2 \| command3 \| command410.循环中; do , ; then 应该和 if/for/while 放在同一行。 else 应该单独一行结束语句应该单独一行并且跟开始语句垂直对齐。 例如
for dir in ${dirs_to_cleanup}; doif [[ -d ${dir}/${ORACLE_SID} ]]; thenlog_date Cleaning up old files in ${dir}/${ORACLE_SID}rm ${dir}/${ORACLE_SID}/*if [[ $? -ne 0 ]]; thenerror_messagefielsemkdir -p ${dir}/${ORACLE_SID}if [[ $? -ne 0 ]]; thenerror_messagefifi
done11.case语句模式表达式前面不应该出现左括号。避免使用 ; 和 ;; 符号。关键规则如下 * 通过2个空格缩进可选项。 * 在同一行可选项的模式右圆括号之后和结束符 ;; 之前各需要一个空格。 * 长可选项或者多命令可选项应该被拆分成多行模式、操作和结束符 ;; 在不同的行。 例子1
case ${expression} ina)variable...some_command ${variable} ${other_expr} ...;;absolute)actionsrelativeanother_command ${actions} ${other_expr} ...;;*)error Unexpected expression ${expression};;
esac例子2
verbosefalse
aflag
bflag
files
while getopts abf:v flag; docase ${flag} ina) aflagtrue ;;b) bflagtrue ;;f) files${OPTARG} ;;v) verbosetrue ;;*) error Unexpected option ${flag} ;;esac
done12.变量扩展应该保持跟你所发现的一致引用你的变量推荐用 ${var} 而不是 $var 例如
# Section of recommended cases.# Preferred style for special variables:
echo Positional: $1 $5 $3
echo Specials: !$!, -$-, _$_. ?$?, #$# *$* $ \$$$ ...# Braces necessary:
echo many parameters: ${10}# Braces avoiding confusion:
# Output is a0b0c0
set -- a b c
echo ${1}0${2}0${3}0# Preferred style for other variables:
echo PATH${PATH}, PWD${PWD}, mine${some_var}
while read f; doecho file${f}
done (ls -l /tmp)# Section of discouraged cases# Unquoted vars, unbraced vars, brace-quoted single letter
# shell specials.
echo a$avar b$bvar PID${$} ${1}# Confusing use: this is expanded as ${1}0${2}0${3}0,
# not ${10}${20}${30}
set -- a b c
echo $10$20$3013.引用 除非需要小心不带引用的扩展否则总是引用包含变量、命令替换符、空格或shell元字符的字符串推荐引用是单词的字符串而不是命令选项或者路径名千万不要引用整数注意 [[ 中模式匹配的引用规则请使用 $ 除非你有特殊原因需要使用 $* 例如
# Single quotes indicate that no substitution is desired.
# Double quotes indicate that substitution is required/tolerated.# Simple examples
# quote command substitutions
flag$(some_command and its args $ quoted separately)# quote variables
echo ${flag}# never quote literal integers
value32
# quote command substitutions, even when you expect integers
number$(generate_number)# prefer quoting words, not compulsory
readonly USE_INTEGERtrue# quote shell meta characters
echo Hello stranger, and well met. Earn lots of $$$
echo Process $$: Done making \$\$\$.# command options or path names
# ($1 is assumed to contain a value here)
grep -li Hugo /dev/null $1# Less simple examples
# quote variables, unless proven false: ccs might be empty
git send-email --to ${reviewers} ${ccs:--cc ${ccs}}# Positional parameter precautions: $1 might be unset
# Single quotes leave regex as-is.
grep -cP ([Ss]pecial|\|?characters*)$ ${1:$1}# For passing on arguments,
# $ is right almost everytime, and
# $* is wrong almost everytime:
#
# * $* and $ will split on spaces, clobbering up arguments
# that contain spaces and dropping empty strings;
# * $ will retain arguments as-is, so no args
# provided will result in no args being passed on;
# This is in most cases what you want to use for passing
# on arguments.
# * $* expands to one argument, with all args joined
# by (usually) spaces,
# so no args provided will result in one empty string
# being passed on.
# (Consult man bash for the nit-grits ;-)set -- 1 2 two 3 three tres; echo $# ; set -- $*; echo $#, $)
set -- 1 2 two 3 three tres; echo $# ; set -- $; echo $#, $)14.命令替换应使用$(command) 而不是反引号
# This is preferred:
var$(command $(command1))# This is not:
varcommand \command1\15.test, [和[[时推荐使用 [[ ... ]] 而不是 [ , test , 和 /usr/bin/[
# This ensures the string on the left is made up of characters in the
# alnum character class followed by the string name.
# Note that the RHS should not be quoted here.
# For the gory details, see
# E14 at http://tiswww.case.edu/php/chet/bash/FAQ
if [[ filename ~ [^[:digit:]]name ]]; thenecho Match
fi# This matches the exact pattern f* (Does not match in this case)
if [[ filename f* ]]; thenecho Match
fi# This gives a too many arguments error as f* is expanded to the
# contents of the current directory
if [ filename f* ]; thenecho Match
fi16.测试字符串尽可能使用引用而不是过滤字符串 例子1
# Do this:
if [[ ${my_var} some_string ]]; thendo_something
fi# -z (string length is zero) and -n (string length is not zero) are
# preferred over testing for an empty string
if [[ -z ${my_var} ]]; thendo_something
fi# This is OK (ensure quotes on the empty side), but not preferred:
if [[ ${my_var} ]]; thendo_something
fi# Not this:
if [[ ${my_var}X some_stringX ]]; thendo_something
fi例子2
# Use this
if [[ -n ${my_var} ]]; thendo_something
fi# Instead of this as errors can occur if ${my_var} expands to a test
# flag
if [[ ${my_var} ]]; thendo_something
fi17.文件名的通配符扩展当进行文件名的通配符扩展时请使用明确的路径
# Heres the contents of the directory:
# -f -r somedir somefile# This deletes almost everything in the directory by force
psabilby$ rm -v *
removed directory: somedir
removed somefile# As opposed to:
psabilby$ rm -v ./*
removed ./-f
removed ./-r
rm: cannot remove ./somedir: Is a directory
removed ./somefile18.Eval应该避免使用 eval简单例子
# What does this set?
# Did it succeed? In part or whole?
eval $(set_my_variables)# What happens if one of the returned values has a space in it?
variable$(eval some_function)19.不建议管道导向while循环20.函数名使用小写字母并用下划线分隔单词。使用双冒号 :: 分隔库。函数名之后必须有圆括号。关键词 function 是可选的但必须在一个项目中保持一致
# Single function
my_func() {...
}# Part of a package
mypackage::my_func() {...
}当函数名后存在 () 时关键词 function 是多余的。但是其促进了函数的快速辨识。
21.变量名如函数名命名相同循环的变量名应该和循环的任何变量同样命名
for zone in ${zones}; dosomething_with ${zone}
done22.常量和环境变量名全部大写用下划线分隔声明在文件的顶部
# Constant
readonly PATH_TO_FILES/some/path# Both constant and environment
declare -xr ORACLE_SIDPROD动态生成的常量可以使用readonly 和 export来进行设置在函数中declare不会对全局变量进行操作。
VERBOSEfalse
while getopts v flag; docase ${flag} inv) VERBOSEtrue ;;esac
done
readonly VERBOSE23.源文件名使用小写如果需要的话使用下划线分隔单词24.只读变量使用readonly 或者 declare -r 来确保变量只读
zip_version$(dpkg --status zip | grep Version: | cut -d -f 2)
if [[ -z ${zip_version} ]]; thenerror_message
elsereadonly zip_version
fi25.本地变量使用 local 声明特定功能的变量。声明和赋值应该在不同行。local作用域为函数内部和子函数中可见。
my_func2() {local name$1# Separate lines for declaration and assignment:local my_varmy_var$(my_func) || return# DO NOT do this: $? contains the exit code of local, not my_funclocal my_var$(my_func)[[ $? -eq 0 ]] || return...
}26.函数位置将文件中所有的函数一起放在常量下面。不要在函数之间隐藏可执行代码27.主函数main为了方便查找程序的开始将主程序放入一个称为 main 的函数作为最下面的函数28.检查返回值使用 $? 或直接通过一个 if 语句来检查以保持其简洁 例子1
if ! mv ${file_list} ${dest_dir}/ ; thenecho Unable to move ${file_list} to ${dest_dir} 2exit ${E_BAD_MOVE}
fi# Or
mv ${file_list} ${dest_dir}/
if [[ $? -ne 0 ]]; thenecho Unable to move ${file_list} to ${dest_dir} 2exit ${E_BAD_MOVE}
fi例子2Bash内部PIPESTATUS变量 -作用
tar -cf - ./* | ( cd ${dir} tar -xf - )
if [[ ${PIPESTATUS[0]} -ne 0 || ${PIPESTATUS[1]} -ne 0 ]]; thenecho Unable to tar files to ${dir} 2
fi例子3PIPESTATUS优化
tar -cf - ./* | ( cd ${DIR} tar -xf - )
return_codes(${PIPESTATUS[*]})
if [[ ${return_codes[0]} -ne 0 ]]; thendo_something
fi
if [[ ${return_codes[1]} -ne 0 ]]; thendo_something_else
fi29.内建命令和外部命令选择上请使用内建命令
# Prefer this:
addition$((${X} ${Y}))
substitution${string/#foo/bar}# Instead of this:
addition$(expr ${X} ${Y})
substitution$(echo ${string} | sed -e s/^foo/bar/)