概述
前言
完全shell菜鸟,以Orange Pi Linux 5.4 SDK编译启动脚本build.sh学习shell,对不懂的语法、命令记录。
一、获取当前文件夹绝对路径
SRC="$(dirname "$(realpath "${BASH_SOURCE[0]}")")"
1.BASH_SOURCE[0]
BASH_SOURCE[0] 等价于BASH_SOURCE, 取得当前执行的shell文件所在的路径及文件名。
2.realpath
realpath 用于获取指定目录或文件的绝对路径。
编写 Shell 脚本中,通常会使用相对路径来指明文件,但有时候,我们需要用到绝对路径,此时可以使用 realpath 来获取。
例如:
zfeng@ubuntu:~/test$ realpath debug.sh
/home/zfeng/test/debug.sh
3.dirname
dirname命令去除文件名中的非目录部分,删除最后一个“”后面的路径,显示父目录。 语法:dirname [选项] 参数
例如:
zfeng@ubuntu:~/test$ dirname /home/zfeng/test
/home/zfeng
二、检查路径是否有空格
grep -q "[[:space:]]" <<<"${SRC}" && { echo ""${SRC}" contains whitespace. Not supported. Aborting." >&2 ; exit 1 ; }
1.grep -q
加-q选项,执行结果是:如果找到了,会返回0;否则,返回1。类似if逻辑判断
例如:
zfeng@ubuntu:~/test$ cat out.txt
1
2
3
zfeng@ubuntu:~/test$ grep -q 1 out.txt
zfeng@ubuntu:~/test$ echo $?
0
zfeng@ubuntu:~/test$ grep -q 9 out.txt
zfeng@ubuntu:~/test$ echo $?
1
其中,$? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误。
2."[[:space:]]"
表示空格
3.<<<
将后面的内容作为前面命令的标准输入。
4.&&
&&运算符
command1 && command2
&&左边的命令(命令1)返回真(即返回0,成功被执行)后,&&右边的命令(命令2)才能够被执行。
5.>&2
shell上:
0表示标准输入
1表示标准输出
2表示标准错误输出
> 默认为标准输出重定向,与 1> 相同
不懂的可以参考一下,总结起来就是:是把结果输出到和标准错误一样。
Linux shell中2>&1的含义解释 (全网最全,看完就懂)
Shell 输入/输出重定向
6.exit 1
exit(0):正常运行程序并退出程序;
exit(1):非正常运行导致退出程序;
exit 0 可以告知你的程序的使用者:你的程序是正常结束的。如果 exit 非 0 值,那么你的程序的使用者通常会认为你的程序产生了一个错误。
在 shell 中调用完你的程序之后,用 echo $? 命令就可以看到你的程序的 exit 值。在 shell 脚本中,通常会根据上一个命令的 $? 值来进行一些流程控制。
三、启用脚本语法
if [[ -f "${SRC}"/scripts/general.sh ]]; then
# shellcheck source=scripts/general.sh
source "${SRC}"/scripts/general.sh
else
echo "Error: missing build directory structure"
echo "Please clone the full repository by https://github.com/orangepi-xunlong/orangepi-build"
exit 255
fi
1.-f
-f 文件存在
配合if语句就是要是该目录下的文件存在,执行then。
2.source
source命令也称为“点命令”,也就是一个点符号(.),是bash的内部命令。
四、获取管理员权限
if [[ $EUID == 0 ]] || [[ "$1" == vagrant ]]; then
:
elif [[ "$1" == docker || "$1" == dockerpurge || "$1" == docker-shell ]] && grep -q `whoami` <(getent group docker); then
:
else
display_alert "This script requires root privileges, trying to use sudo" "" "wrn"
sudo "$SRC/build.sh" "$@"
exit $?
fi
非管理员执行的打印信息如下
zfeng@ubuntu:~/orangepi/orangepi-build$ ./build.sh
[ warn ] This script requires root privileges, trying to use sudo
[sudo] zfeng 的密码:
第一个if检查是否是管理员运行,要是不是则通过elif后面内容查找当前用户名。
1.EUID
linux系统中每个进程都有2个ID,分别为用户ID(uid)和有效用户ID(euid),UID一般表示进程的创建者(属于哪个用户创建),而EUID表示进程对于文件和资源的访问权限(具备等同于哪个用户的权限)。其中管理员的UID固定为0。
zfeng@ubuntu:~$ echo $EUID
1000
zfeng@ubuntu:~$ su
密码:
root@ubuntu:/home/zfeng# echo $EUID
0
2."$1" == vagrant “$1” == docker || “$1” == dockerpurge || “$1” == docker-shell
Vagrant 是一个基于 Ruby 的工具,用于创建和部署虚拟化开发环境。
Docker是一个虚拟环境容器。
dockerpurge
docker-shell
$0、$1、$2的含义:
$0 就是你写的shell脚本本身的名字,$1 是你给你写的shell脚本传的第一个参数,$2 是你给你写的shell脚本传的第二个参数。如下:
root@ubuntu:/home/zfeng/test# cat $012.sh
#!/bin/sh
echo "shell脚本本身的名字: $0"
echo "传给shell的第一个参数: $1"
echo "传给shell的第二个参数: $2"
root@ubuntu:/home/zfeng/test# ./$012.sh 1 2
shell脚本本身的名字: ./bash12.sh
传给shell的第一个参数: 1
传给shell的第二个参数: 2
3.whoami
whoami是操作系统中用于查看当前有效用户名的命令。
zfeng@ubuntu:~$ whoami
zfeng
4.grep -q whoami
<(getent group docker)
不是很懂,猜测可能是查找当前的用户名。
5.$@
$@ 传递给脚本或函数的所有参数。详见这里
五、更新脚本
git pull
CHANGED_FILES=$(git diff --name-only)
CHANGED_FILES=$(git diff --name-only)
git diff --name-only 只列变更文件。
六、检查编译环境
if [[ -z "$(which whiptail)" ]]; then
sudo apt-get update
sudo apt-get install -y whiptail
fi
if [[ -z "$(which getfacl)" ]]; then
sudo apt-get update
sudo apt-get install -y acl
fi
# Check for Vagrant
if [[ "$1" == vagrant && -z "$(which vagrant)" ]]; then
display_alert "Vagrant not installed." "Installing"
sudo apt-get update
sudo apt-get install -y vagrant virtualbox
fi
1.if [[ -z “$(which whiptail)” ]];
[ -z STRING ] “STRING” 的长度为零则为真。
2.whiptail
交互式shell脚本对话框
zfeng@ubuntu:~/test$ whiptail --title "Message box title" --msgbox " Choose Ok to continue." 10 60
3.getfacl
获取目录或文件访问控制列表。
zfeng@ubuntu:~/test$ getfacl -a out.txt
# file: out.txt
# owner: zfeng
# group: zfeng
user::rw-
group::rw-
other::r--
4.vagrant
vagrant是一个工具,用于创建和部署虚拟化开发环境的。
七、检查并创建文件
if ! ls ${SRC}/userpatches/{config-example.conf,config-docker.conf,config-vagrant.conf} 1> /dev/null 2>&1; then
display_alert "Create example config file using template" "config-default.conf" "info"
# Create example config
if [[ ! -f "${SRC}"/userpatches/config-example.conf ]]; then
cp "${EXTER}"/config/templates/config-example.conf "${SRC}"/userpatches/config-example.conf || exit 1
ln -fs config-example.conf "${SRC}"/userpatches/config-default.conf || exit 1
fi
1./dev/null
表示的是一个黑洞,通常用于丢弃不需要的数据输出, 或者用于输入流的空文件。
2.1> /dev/null 2>&1
意思就是把标准输出重定向到“黑洞”,还把错误输出2重定向到标准输出1,也就是标准输出和错误输出都进了“黑洞”。
3.ln -fs
ln(英文全拼:link files)命令是一个非常重要命令,它的功能是为某一个文件在另外一个位置建立一个同步的链接。
当我们需要在不同的目录,用到相同的文件时,我们不需要在每一个需要的目录下都放一个必须相同的文件,我们只要在某个固定的目录,放上该文件,然后在 其它的目录下用ln命令链接(link)它就可以,不必重复的占用磁盘空间。
参数 -f 强制执行 -s 软链接(符号链接)
详见Linux ln 命令
最后
以上就是辛勤红酒为你收集整理的shell 学习记录(一)-Orange Pi Linux 5.4 SDK启动脚本build.sh前言一、获取当前文件夹绝对路径二、检查路径是否有空格三、启用脚本语法四、获取管理员权限五、更新脚本六、检查编译环境七、检查并创建文件的全部内容,希望文章能够帮你解决shell 学习记录(一)-Orange Pi Linux 5.4 SDK启动脚本build.sh前言一、获取当前文件夹绝对路径二、检查路径是否有空格三、启用脚本语法四、获取管理员权限五、更新脚本六、检查编译环境七、检查并创建文件所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复