前言:
今天給大家分享一篇在我工作中常用的一個(gè)
shell腳本,里面有一些我們常用到的shell操作。該腳本用于本地電腦和服務(wù)器交互上,實(shí)現(xiàn)以下功能:
-
自動(dòng)拉取自己個(gè)人電腦上的源碼到服務(wù)器上yocto包的源碼文件夾。
-
自動(dòng)運(yùn)行compile 、strip
-
自動(dòng)把編譯好的結(jié)果回傳到個(gè)人電腦上。
-
拷貝執(zhí)行文件到機(jī)器中
作者:良知猶存
轉(zhuǎn)載授權(quán)以及圍觀:歡迎關(guān)注微信公眾號(hào):羽林君
或者添加作者個(gè)人微信:become_me
情節(jié)介紹:
在工作中,我們經(jīng)常會(huì)遇到需要把修改的代碼放到服務(wù)器去編譯,然后把編譯好的文件放到機(jī)器板卡對(duì)應(yīng)的文件。這個(gè)過(guò)程如果我們使用命令的話,大概有七八條,完成操作完之后 ,大約會(huì)花費(fèi)一分。雖然花費(fèi)的時(shí)間不算多,但是你也會(huì)一直關(guān)注終端,然后等待輸入命令,需要花費(fèi)不小精力。但是我們可以寫一些
shell腳本來(lái)輔助我們的工作。今天就是給大家分享使用的腳本,一邊分享使用過(guò)程,一邊分享里面用到的shell技術(shù)點(diǎn)。包含,if判斷、switch case條件、字符截取、遠(yuǎn)程調(diào)用腳本、兩種免密登陸等。
三者的使用過(guò)程為:本地通過(guò)腳本輸入?yún)?shù)選擇使用wifi分配的ip還是網(wǎng)線分配的ip,然后進(jìn)行ip數(shù)據(jù)傳參形式 遠(yuǎn)程調(diào)用預(yù)先放置好的——服務(wù)器編譯腳本,服務(wù)器腳本通過(guò)傳入的ip參數(shù),免密scp拷貝本地的文件到服務(wù)器執(zhí)行目錄,服務(wù)器執(zhí)行編譯工作,然后拷貝到本地的指定目錄,最后調(diào)用本地的expect免密登陸的腳本,拷貝文件到機(jī)器中。
腳本一:本地選擇腳本auto_build.sh
腳本內(nèi)容如下:
#/bin/bash
remote_ip=172.160.111.32
remote_hostname=lyn
case $1 in
1)
echo -e
'\033[0;42m Ethernet dhcp \033[0m'
VAR=
"eno1"
;;
2)
echo -e
'\033[0;46m wireless dhcp \033[0m'
VAR=
"wlo1"
;;
esac
HOST_IP=$(ifconfig
$VAR | grep
"inet" | grep -v inet6| awk
'{ print $2}' | awk -F:
'{print $1}')
echo "parse ip is:" $HOST_IP
if [[ ! -n
"${HOST_IP}" ]] ;
then
echo -e
"\033[0;31m input local ip \033[0m"
read local_ip
else
if [[ ! $(
echo "${HOST_IP}" | awk -F.
'{printf $1}') ==
"192" ]] ;
then
local_ip=
$HOST_IP
else
echo -e
"\033[0;31m error ip \033[0m"
exit 0
fi
fi
#exit 0
if [[
$2 == 1 ]];
then
build_opt=
"all_build"
else
build_opt=
fi
ssh -t
${remote_hostname}@
${remote_ip} "/home/lyn/build.sh ip=${local_ip} ${build_opt}"
這個(gè)部分有幾處技術(shù)使用:
switch case使用,if else、免密登陸,遠(yuǎn)程調(diào)用腳本。
首先是一個(gè)switch case
此處作用是進(jìn)行ip地址的篩選,因?yàn)榈脑谡{(diào)試過(guò)程中,我的電腦有時(shí)候用網(wǎng)線連接,有時(shí)候會(huì)去測(cè)試房去測(cè)試,用wifi連接,這個(gè)時(shí)候會(huì)進(jìn)行網(wǎng)絡(luò)ip地址的區(qū)分,當(dāng)我輸入./auto_build.sh 1的時(shí)候,腳本會(huì)進(jìn)行解析eno1網(wǎng)線分配的ip地址,當(dāng)我輸入./auto_build.sh 2的時(shí)候則會(huì)解析wlo1wifi分配的ip。
在里面我還用了顏色打印,進(jìn)行關(guān)鍵詞的標(biāo)注,如下所示:
關(guān)于顏色打印的部分這個(gè)是另一個(gè)知識(shí),這是一個(gè)轉(zhuǎn)義的實(shí)際使用過(guò)程,通過(guò)特定符號(hào)的轉(zhuǎn)義識(shí)別,我們?cè)贚inux終端去顯示不同顏色的打印輸出,這個(gè)是我們經(jīng)常使用的操作,例如log等級(jí)分級(jí)打印時(shí)候,error是紅色,正常是綠色,普通是白色等。
顏色打印大致介紹如下:
轉(zhuǎn)義序列以控制字符'ESC'開頭。該字符的ASCII碼十進(jìn)制表示為27,十六進(jìn)制表示為0x1B,八進(jìn)制表示為033。多數(shù)轉(zhuǎn)義序列超過(guò)兩個(gè)字符,故通常以'ESC'和左括號(hào)'['開頭。該起始序列稱為控制序列引導(dǎo)符(CSI,Control Sequence Intro),通常由 '\033[' 或 '\e[' 代替。
通過(guò)轉(zhuǎn)義序列設(shè)置終端顯示屬性時(shí),可采用以下格式:
\033[ Param {;Param;...}m
或
\e[ Param {;Param;...}m
其中,'\033['或'\e['引導(dǎo)轉(zhuǎn)義序列,'m'表示設(shè)置屬性并結(jié)束轉(zhuǎn)義序列。
因此,通過(guò)轉(zhuǎn)義序列設(shè)置終端顯示屬性時(shí),常見格式為:
\033[顯示方式;前景色;背景色m輸出字符串\033[0m
或\e[顯示方式;前景色;背景色m輸出字符串\033[0m
其中 ,'\033[0m'用于恢復(fù)默認(rèn)的終端輸出屬性,否則會(huì)影響后續(xù)的輸出。
示例:我在此處使用 echo -e '\033[0;42m Ethernet dhcp \033[0m' 進(jìn)行網(wǎng)線端口ip分配的打印,通過(guò)轉(zhuǎn)義之后,打印顏色為帶背景色的綠色顯示。具體對(duì)應(yīng)的顏色,大家可以看一下小麥老兄寫的這篇文章 printf打印還能這么玩。
注:打印log時(shí)候記得echo 要使用 -e參數(shù)。
其次還有組合使用命令實(shí)現(xiàn)獲取本地ip
HOST_IP=$(ifconfig
$VAR | grep
"inet" | grep -v inet6| awk
'{ print $2}' | awk -F:
'{print $1}')
我們一步步查看執(zhí)行情況
第一步:ifconfig eno1
lyn@lyn:~/Documents/work-data/download_data$ ifconfig eno1
eno1: flags=4163
mtu 1500
inet 172.16.30.147 netmask 255.255.255.0 broadcast 172.16.30.255
inet6 fe80::ca7:d954:67e0:7c60 prefixlen 64 scopeid 0x20
ether f8:b4:6a:bd:dd:92 txqueuelen 1000 (Ethernet)
RX packets 3678600 bytes 3470673356 (3.4 GB)
RX errors 0 dropped 36842 overruns 0 frame 0
TX packets 2229431 bytes 995696588 (995.6 MB)
TX errors 0
我們經(jīng)常使用ifconfig查看ip,但是使用ifconfig返回的數(shù)據(jù)過(guò)多,而我們實(shí)際使用的部分只是一部分而已。
所以我們使用ifconfig指定設(shè)備查找ip,篩去無(wú)用信息。
第二步:ifconfig eno1 | grep "inet"
把第一步查詢的信息通過(guò) | 產(chǎn)生一個(gè)管道傳遞給下一個(gè)命令,用grep查找有inet字符的行數(shù)據(jù),顯示如下:
lyn@lyn:~/Documents/work-data/download_data$ ifconfig eno1 | grep "inet"
inet 172.16.30.147 netmask 255.255.255.0 broadcast 172.16.30.255
inet6 fe80::ca7:d954:67e0:7c60 prefixlen 64 scopeid 0x20
因?yàn)槲覀冎恍枰猧pv4協(xié)議的ip,所以我們要去掉inet6對(duì)應(yīng)的地址
第三步:ifconfig eno1 | grep "inet" | grep -v inet6
使用grep -v命令去掉 inet6 關(guān)鍵詞的對(duì)應(yīng)一行信息
lyn@lyn:~/Documents/work-data/download_data$ ifconfig eno1 | grep "inet" | grep -v inet6
inet 172.16.30.147 netmask 255.255.255.0 broadcast 172.16.30.255
第四步:ifconfig eno1 | grep "inet" | grep -v inet6 | awk '{ print$2}'
使用 awk處理文本文件的語(yǔ)言進(jìn)行處理數(shù)據(jù),$2 表示默認(rèn)以空格分割的第二組 ,-F:-F指定分隔符為 ‘ : ’
lyn@lyn:~/Documents/work-data/download_data$ ifconfig eno1 | grep "inet" | grep -v inet6| awk '{ print$2}'
172.16.30.147
關(guān)于grep sed awk的使用大家也可以網(wǎng)上具體查看一下,但是我們一般使用過(guò)程中,grep 更適合單純的查找或匹配文本, sed 更適合編輯匹配到的文本,awk 更適合格式化文本,對(duì)文本進(jìn)行較復(fù)雜格式處理。
這個(gè)時(shí)候我們從本機(jī)得到了ip地址。我們需要進(jìn)行遠(yuǎn)程調(diào)用服務(wù)器腳本,并把ip以參數(shù)形式傳入。
其次ssh免密登陸和ssh遠(yuǎn)程執(zhí)行任務(wù)
首先第一個(gè)部分就是ssh免密登陸
本地執(zhí)行ssh到服務(wù)的相關(guān)操作命令需要免密,服務(wù)器scp本地文件也要免密登陸,那么如何設(shè)置我們ssh相關(guān)命令操作,無(wú)需密碼呢?
SSH分客戶端openssh-client和服務(wù)器openssh-server如果你只是想登陸別的機(jī)器,只需要安裝openssh-client(ubuntu有默認(rèn)安裝,如果沒(méi)有則sudo apt-get install openssh-client),如果要使別的機(jī)器登陸本機(jī)就需要在本機(jī)安裝openssh-server(sudo apt-get install openssh-server)
我們可以使用 ps -e | grep ssh 來(lái)查看對(duì)應(yīng)的openssh-client和openssh-server運(yùn)行情況,其中ssh是client ,sshd是server,哪個(gè)缺我們就使用apt-get install 。
sudo service ssh start 安裝之后可以使用這個(gè)命令啟動(dòng)。
準(zhǔn)備好了對(duì)應(yīng)的server和client接下來(lái),把我們生成的rsa公鑰拷貝要對(duì)應(yīng)要登陸的機(jī)器,即可免密登陸。
1.客戶端生成公私鑰
ssh-keygen 命令一路回車默認(rèn)生成
這個(gè)命令會(huì)在用戶目錄.ssh文件夾下創(chuàng)建公私鑰,id_rsa (私鑰),id_rsa.pub (公鑰)。
2.上傳公鑰到服務(wù)器
ssh-copy-id -i ~/.ssh/id_rsa.pub lyn@172.160.111.32
上面這條命令是寫到服務(wù)器上的ssh目錄下去了
vi ~/.ssh/authorized_keys
可以看到客戶端寫入到服務(wù)器的 id_rsa.pub (公鑰)內(nèi)容。
3.測(cè)試免密登錄 客戶端通過(guò)ssh連接遠(yuǎn)程服務(wù)器,就可以免密登錄了。
ssh lyn@172.160.111.32
第二個(gè)部分就是ssh遠(yuǎn)程執(zhí)行服務(wù)器腳本
有時(shí)候我們需要遠(yuǎn)程執(zhí)行一些有交互操作的命令。這個(gè)時(shí)候我們就可以使用ssh加參數(shù)進(jìn)去進(jìn)行遠(yuǎn)程執(zhí)行。
格式如下:
遠(yuǎn)程執(zhí)行一個(gè)命令
ssh lyn@172.160.111.32 "ls -l"
執(zhí)行多條命令,使用分號(hào)把不同的命令隔起來(lái)
ssh lyn@172.160.111.32 "ls;cat test.txt "
遠(yuǎn)程執(zhí)行本地腳本
ssh lyn@172.160.111.32 < test.sh
遠(yuǎn)程執(zhí)行本地的腳本(執(zhí)行帶有參數(shù)的腳本),需要為 bash 指定 -s 參數(shù):
ssh lyn@172.160.111.32 'bash -s' < test.sh helloworld
執(zhí)行遠(yuǎn)程的腳本
ssh lyn@172.160.111.32 "/home/lyn/test.sh"
注,此時(shí)需要指定腳本的絕對(duì)路徑!
而我們使用的為遠(yuǎn)程執(zhí)行腳本,最終ssh遠(yuǎn)程執(zhí)行如下:
remote_ip=172.160.111.32
remote_hostname=lyn
local_ip=172.16.30.147
build_opt=
ssh -t ${remote_hostname}@${remote_ip} "/home/lyn/build.sh ip=${local_ip} ${build_opt}"
腳本二:服務(wù)器編譯腳本 build.sh
腳本內(nèi)容如下:
#!/bin/bash -e
scp_dir=/media/lyn/win_data/lyn_workdata/working/robot-ctl
download_data=/home/lyn/Documents/work-data/download_data
build_dir=/home/lyn/projects/yocto/yocto-build/tmp/work/aarch64-poky-linux/robot-ctl/git-r0/git/
image_dir=/home/lyn/projects/yocto/yocto-build/tmp/work/aarch64-poky-linux/robot-ctl/git-r0/image/robot-ctl/
remote_exec_file_dir=/home/lyn/Documents/work-data/download_data/scp_exec.sh
all_build=No
wifi_src=No
only_scp_robot=No
strip_mode=No
ip_wireless_dhcp=170.160.111.45
ip_ethernet_dhcp=170.160.111.147
local_ip=${ip_wireless_dhcp}
host_name=lyn
date
echo -e "\033[0;31m Loading options.\033[0m"
# Load all the options.
if [ $# -eq 0 ];then
echo -e "\033[33;5m no argument \033[0m"
fi
for arg in "${@}"
do
if [[ -n "${arg}" ]]
本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。