陈晓猫

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

linux脚本编写备忘
1、linux脚本的回车换行符最好用unix格式的。否则某些系统下运行会出错,例如veket18中必须要求是LF格式。
Unix 系统(包括 Linux 和 macOS):使用 LF (Line Feed, \n) 字符作为行结束符。在 ASCII 码表中,LF 字符的十进制表示为 10。
Windows 系统:使用 CR LF (Carriage Return Line Feed, \r\n) 字符序列作为行结束符。在 ASCII 码表中,CR 字符的十进制表示为 13,LF 字符的十进制表示为 10。

2、linux脚本最好用utf-8编码,如果在windows下面用GBK编码,可能会导致在linux下面编辑出现乱码的情况,而且grub4dos/grub2都要求是utf-8无BOM编码格式。

3、有些命令需要root权限,脚本开头的时候可以做个判断:
[ "`whoami`" != "root" ] && exec sudo -A ${0} ${@}

4、#变量不区分大小写比较:
shopt -s nocasematch

5、变量使用括号和不使用花括号{}的主要区别在于它们如何处理变量名称和周围的字符。
使用花括号可以明确地界定变量的名称,特别是当变量名称与其他字符相邻或者变量名称包含特殊字符时。这可以防止歧义,并确保变量被正确地替换。
my_var="value"
echo "${my_var}" # 输出 value
如果变量名称包含特殊字符或空格,使用括号是必须的:
my_var_with_underscores="value"
echo "${my_var_with_underscores}" # 输出 value
在大多数情况下,推荐使用花括号 {} 来引用变量,因为它提供了更好的可读性和更明确的行为。特别是在复杂的表达式或脚本中,使用花括号可以避免很多常见的错误。
允许访问数组的特定索引或字符串的长度。
my_var="Hello World"
echo "${my_var[@]}" # 输出所有的单词
echo "${#my_var}" # 输出字符串长度

6、使用圆括号 () 与变量相关的情况通常不是引用变量,而是与命令替换、算术扩展或子 shell 执行有关。以下是一些使用圆括号的场景:
(1)命令替换:使用 $(...) 或 `...` 来进行命令替换,即执行括号内的命令,并将输出替换为一个字符串。
output=$(ls -l)
echo "$output"
(2)算术扩展:
使用 $(( ... )) 来进行算术运算。
num=$(( 1 + 1 ))
echo "The sum is $num"
请注意,当引用变量时,通常使用花括号 {} 而不是圆括号 ()。花括号用于防止变量名与周围的文本混合,特别是在变量名之后紧跟着其他字符时。例如:
my_var="value"
echo "${my_var}_suffix" # 输出 value_suffix

8、变量取默认值的方法:
# 读取用户输入并根据输入执行相应逻辑
read -p "请输入数字(直接回车=1):" xb
xb=${xb:-1} # 如果未输入,则默认为1

9、变量含有某个字符串,模糊查找、取反的办法:
if [[ "$x" =~ "veket" ]]; then # 检查变量 x 是否包含 "veket" 子字符串
if [[ ! "$x" =~ "veket" ]]; then # 检查变量 x 是否不包含 "veket" 子字符串
if [[ ${mydir: -4} == ".wim" ]] || [[ ${mydir: -4} == ".img" ]] || [[ ${mydir: -4} == ".vhd" ]]; then

10、逻辑判断[] [[]]区别
在 Bash 脚本中,[[]] 和 [ ] 都用于条件表达式的测试,但它们之间存在一些差异:
(1)[ ](传统的测试命令)
传统的测试命令,也被称为 test 命令。
使用空格来分隔参数和操作符。
字符串的引用需要使用双引号 " 来防止字符串被拆分为多个参数。
不支持 < 和 > 作为重定向操作符,需要使用 "$( ... )" 来进行命令替换。
if [ "$string" = "test" ]; then
echo "String is test"
fi
(2)[[ ... ]](扩展的测试命令)
提供了更多的特性和扩展功能。
支持模式匹配(使用 == 和 !=)。
支持正则表达式匹配(使用 =~)。
支持对变量进行间接扩展(使用 !varname 或 ${!varname})。
支持进程替换(使用 <( ... ) 和 >( ... ))。
允许在条件中使用 && 和 || 作为逻辑运算符。
字符串的引用可以使用双引号 " 或单引号 ',后者不会展开变量和特殊字符。
if [[ "$string" == "test" ]]; then
echo "String is test"
fi
(3)逻辑判断区别
[ ] 和 [[ ... ]] 在逻辑判断上基本相同,但 [[ ... ]] 由于其扩展性,可以更灵活地编写复杂的条件表达式。
(4)空字符串和未定义变量的处理
[[ ... ]] 在处理空字符串或未定义的变量时,通常更加严格和一致。例如,[[ -z $var ]] 会正确地测试变量是否为空字符串,即使变量未定义。
(5)优先级和求值
[[ ... ]] 允许使用 && 和 || 进行逻辑运算,而 [ ] 不支持这种用法。在 [[ ... ]] 中,逻辑运算符可以在条件表达式中直接使用,而 [ ] 中则需要使用 -a 和 -o。
(6)兼容性
[ ] 是 POSIX 标准的一部分,几乎所有的 Unix-like 系统都支持。
[[ ... ]] 是 Bash 特有的,虽然在大多数现代 shell 中也得到了支持,但可能在一些非常老的或非 Bash shell 中不可用。
总结来说,[[ ... ]] 提供了更多的特性和更好的灵活性,是编写 Bash 脚本时的首选。然而,如果你需要确保脚本的兼容性,特别是在非 Bash shell 环境中,使用 [ ] 可能更合适。

11、判断某个命令可用执行A,否则执行B。
if which fdisk >/dev/null; then #如果fdisk命令可用,就用fdisk -l命令
echo fdisk -l命令可用。
elif which parted >/dev/null; then #如果fdisk命令不可用,就用parted -l -m命令
echo parted -l -m命令可用。
fi

12、中英文的提示自适应的办法,建议用变量。
# 获取当前的语言环境
lang_env=$LANG
if [ -z "$lang_env" ]; then
lang_env=$LC_ALL
fi

# 检查语言环境是否包含中文标识
if [[ "$lang_env" == *"zh"* ]]; then
# echo "当前操作系统的语言设置为中文。"
title="BIOS启动模式安装"
else
# echo "当前操作系统的语言设置为英文或其他语言。"
title="BIOS mode setup"
fi

13、一般地要求子函数放在前面,主程序放在后面,否则运行会出错。

14、代码建议根据逻辑结构进行缩进,缩进的主要目的是为了代码的结构清晰和逻辑层次分明。建议用好用点的编辑器编辑,在windows下面我用的是notepad2。

15、sed命令,有的时候要用单引号,有的时候建议用双引号,要活学活用。
(1)sed用s命令搜索替换的时候,定界符可以更改,定界符取决于s命令之后的第一个字符,定界符更改之后,/字符就不用再转义了,比较方便。例如:
#rem 去掉盘符,把/改成\/:x2=/linux/veket/wps-veket20200513/veket_20,rem 把空格替换为\\空格:
x2=$(echo "${mydir}" | sed -e 's#.*/mnt/[^/]*/#/#' -e 's#\/#\\\/#g' -e 's#[ ]#\\\\ #g')
(2)如果用pattern模式搜索的时候,可能会涉及到逻辑取反,这时候就要用单引号,此时里面的变量要用单引号包围起来。注意此时定界符必须用/,例如:
#删除 title+xxx.iso 到下一个 title 之间的所有行,注意此时sed -e命令此时必须用单引号,被搜索的变量关键字必须用单引号包围起来,否则感叹号逻辑取反会出错。
sed -e '/title.*'${x2}'\/'${x3}'/{:a;$!N;/\ntitle/!{s/\n.*//;ta};/title/!P;D}' -i "$menu"
(3)sed用i命令插入文本的时候,建议用双引号,这样子会把里面的变量“引用”出来,比较方便。例如:
sed -e "${y}i\title ${x2}\/${x3}-kernel ntloader\nfind --ignore-floppies --ignore-cd /boot/grub/ntloader | set bd= ;; echo bd=%bd%\nfind --ignore-floppies --ignore-cd --set-root ${x2}\/${x3}\nuuid ()\nkernel %bd%/boot/grub/ntloader uuid=\%?_UUID% file=${x2}\/${x3} hires=1\ninitrd %bd%/boot/grub/initrd.lz1\n" -i $menu

16、grep命令,如果想要用通配符,就应该用grep -E "*.iso",或者用egrep "*.iso"命令。如果不需要通配符,可以直接用grep "iso"。

17、程序完成后按任意键退出的办法:
read -p "veket已安装完毕,按任意键退出。" -r -n 1 -s

posted on 2024-06-09 08:20  陈晓猫  阅读(28)  评论(0编辑  收藏  举报