shell入门之一
第1章 shell入門
? shell是一個命令解釋器,它的操作系統的最外層,負責直接與用戶對話,把用戶的輸入解釋給操作系統,并處理各種二樣的操作系統的輸出結果,輸出屏幕返回給用戶
? 對話的方式可以是:
? 交互式方式:從鍵盤輸入命令,通過/bin/bash 解析,可以立即得到shell的回應
? 非交互式方式:腳本
?
1.1 下圖就是命令解釋器:
?
?
?
????????? shell是英文是貝殼的意思,命令解釋器shell像一個貝殼一樣包住系統核心
????????? shell執行的命令分為兩種方式:
?
? 內置命令:如講過的cd . pwd exit 和echo 等命令,當用戶登錄系統后,shell以及內置命令就被系統載入到內存,并且一直運行著。
? 一般命令:如ls,磁盤上的程序文件à調入內存à執行命令
?
第2章 什么是shell腳本
? 當linux命令或語句不在命令行下執行(嚴格說,命令行也是shell),而是通過一個程序文件執行時,改程序就被稱為Shell腳本或shell程序
?
? 用戶可以在shell腳本中敲入一系列的命令及命令語句組合。這些命令,變量和流程控制語句等有機的結合起來久形成一個功能強大的shell腳本
?
2.1 首先先帶領大家寫一個清空/var/log/messages日志的腳本
我們需要先想明白幾個問題:
1)?? 日志文件在哪?
/var/log/messages
2)?? 用什么命令可以清空文件?
> 重定向
3)?? 寫一個簡單的shell腳本。
#!/bin/bash
cd /var/log/
>messages4)??? 怎樣執行腳本?
[root@kaile ~]# sh /server/scripts/clear.sh
5)?? 有沒有考慮到:
·????????有沒有腳本放在統一的目錄
/server/scripts目錄下
·????????權限:用哪個用戶執行文件
需要對用戶做判斷
·?????清空錯文件怎么辦,該如何辦?
·?????錯誤提示:有沒有成功知不知道?
·?????腳本的通用性
2.2范例:包含命令,變量和流程控制的清空/var/log/messages日志的shell腳本
[root@kaile ~]# mkdir -p /server/scripts #要有規范的存放腳本目錄
[root@kaile ~]# vim /server/scripts/clear.sh
[root@kaile ~]# cd /server/scripts/
[root@kailescripts]# cat /server/scripts/clear.sh
#!/bin/bash??????????????????????????? #指定解釋器
?
LOG_DIR=/var/log???????????????????????? #設置變量
?
?
if [ "$UID" == "0" ];then?????? UID等于然后執行下面的命令
?cd $LOG_DIR
?>message
?echo "Logclear yes"
fi
~????
清空日志的三種方法:
echo >test.log
>test.log
cat /dev/null>test.log
#清空內容,保留文件
2.3小結:
·????????Shell就是命令解釋器。==>翻譯官
·????????Shell腳本==>命令放在腳本里
2.4Shell腳本在運維工作中的作用地位
? Shell腳本擅長處理純文本類型的數據,而Linux中幾乎所有的配置文件,日志文件等都是純文本類型文件。
2.5Shell腳本的建立和執行
2.61Shell腳本的建立
推薦使用vim編輯器編輯腳本,可以事先做個別名。
[root@kailescripts]# echo "aliasvi=vim">>/etc/profile
[root@kailescripts]# source /etc/profile
2.7腳本開頭第一行
? 規范的Shell腳本第一行會指出由哪個程序(解釋器)來執行腳本中的內容。在linux bash編程中一般為:
#!/bin/bash
或
#!/bin/sh
? 其中開頭的“#!”又稱為幻數,在執行Shell腳本的時候,內核會根據“#!”后的解釋器來確定哪個程序解釋腳本中的內容。注意:這一行必須在每個腳本頂端的第一行,如果不是第一行則為腳本注釋行。
2.8sh和bash的區別
[root@kaile scripts]# ll /bin/sh
lrwxrwxrwx. 1 rootroot 4 Dec 2320:25 /bin/sh -> bash
? #sh是bash的軟鏈接,推薦標準寫法#!/bin/bash
可以看一下系統自帶的腳本的寫法
head -1 /etc/init.d/*
2.93 bash版本
[root@kailescripts]# bash --version
GNU bash,version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2009 FreeSoftware Foundation, Inc.
License GPLv3+:GNU GPL version3or later <http://gnu.org/licenses/gpl.html>
?
This is freesoftware; you are free to changeand redistribute it.
There isNOWARRANTY, to the extent permitted by law.
2.103.1.4 bash漏洞【破殼漏洞】
如果是比較老的系統,需要注意shell的版本太低,有漏洞,需要升級shell
[root@kailescripts]# yum -y update bash
#驗證方法
[root@kailescripts]# env x='(){ :;};echo be careful' bash -c"echo this is a test"
thisis a test
如果返回2行
??? be careful
??? thisis a test
這樣的結果的話,請盡快升級2.11不同語言腳本的開頭寫法
#!/bin/sh
#!/bin/bash
#!/usr/bin/awk
#!/bin/sed
#!/usr/bin/tcl
#!/usr/bin/expect
#!/usr/bin/perl
#!/usr/bin/env python
? 如果腳本開頭不指定解釋器,就要用對應的解釋器執行腳本。例如bashtest.sh和python.test.py
? 要求:養成一個好習慣,開頭加上相應的解釋器標識。
2.12腳本注釋
? 在Shell腳本中,跟在#后面的內容表示注釋。注釋部分不會被執行,僅給人看。注釋可以自成一行,也可以跟在命令后面,與命令同行。要養成寫注釋的習慣,方便自己與他人。
? 最好不用中文注釋,因為在不同字符集的系統會出現亂碼。
2.13Shell腳本的執行
2.14Shell腳本執行的四種方式
? 1)bash scripts-name或sh script-name(推薦使用)
這種方法是當腳本本身沒有可執行權限時常使用的方法。
? 2)path/script-name 或./scripts-name(全路徑或當前路徑執行腳本)
這種方法首先需要給腳本文件可執行權限。
? 3)sourcescripts-name或.scripts-name #注意“.”點號,且點號后有空格。
source 或.在執行這個腳本的同時,可以將腳本中的函數和變量加載到當前Shell。不會產生子shell。又有點像nginx的include功能。
2.15Shell腳本開發的規范和習慣
1)開頭指定腳本解釋器
2)開頭加版本版權等信息,可配置~/.vimrc文件自動添加
3)腳本不要用中文注釋,盡量用英文注釋
4)腳本以.sh為擴展名
5)放在統一的目錄
6)代碼書寫優秀習慣
a,成對的內容一次性寫出來,防止遺漏,如[],'',""等
b,[]兩端要有空格,先輸入[]退格,輸入2個空格,再退格寫。
c,
流程控制語句一次書寫完,再添加內容。
if條件
??? then
????? 內容
fi
d,通過縮進讓代碼易讀
f,腳本中的引號都是英文狀態下的引號,其他字符也是英文狀態。
好的習慣可以讓我們避免很多不必要的麻煩,提高工作效率。
第3章 Shell環境變量
3.1什么是變量
? 變量就是用一個固定的字符串(也可能是字符數字等的組合),替代更多更復雜的內容,這個內容里可能還會包含變量和路徑,字符串等其他內容。變量的定義是存在內存中。
x=1
y=2
x變量?? 一個=賦值?? ==相等
?
定義變量三種方法?
自定義變量?
read? 變量?
參數變量??
3.2變量類型
? 變量分為兩類:
1)環境變量(也可稱為全局變量);可以在創建他們的Shell及派生出來的子shell中使用。環境變量又可以分為自定義環境變量和bash內置的環境變量。
? 2)局部變量(普通變量):只能在創建他們的shell函數或shell腳本中使用,還記得前面的$user我們創建的一般都是普通變量。
3.3環境變量
·????????環境變量用于定義Shell的運行環境,保證Shell命令的正確執行,Shell通過環境變量來確定登錄用戶名,命令路徑,終端類型,登錄目錄等,所有的環境變量都是全局變量,可用于所有子進程中,包括編輯器,shell腳本和各類應用。但crond計劃任務除外,還需要重新定義環境變量。
·????????環境變量可以在命令行中設置,但用戶退出時這些變量值也會丟失,因此最好在用戶家目錄下的.bash_profile文件中或全局配置/etc/bashrc,/etc/profile文件或者/etc/profile.d/目錄中定義。將環境變量放入profile文件中,每次用戶登錄時這些變量值都將被初始化。
·????????通常,所有環境變量均為大寫。環境變量應用于用戶進程前,都應該用export命令導出。例如:exportclear=1
·????????有一些環境變量,比如HOME,PATH,SHELL,UID,USER等,在用戶登錄之前就已經被/bin/login程序設置好了。通常環境變量定義并保存在用戶家目錄下的.bash_profile或/etc/profile文件中。
3.3.1 #顯示環境變量
[root@kailescripts]# echo $HOME
/root
[root@kailescripts]# echo $PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
[root@kailescripts]# echo $SHELL
/bin/bash
[root@kailescripts]# echo $UID
0
[root@kailescripts]# echo $USER
root
?
3.3.2查看系統環境變量
[root@kailescripts]# env #查看系統環境變量
HOSTNAME=kaile
SELINUX_ROLE_REQUESTED=
TERM=xterm-256color
SHELL=/bin/bash
HISTSIZE=500
SSH_CLIENT=192.168.197.149592 22
SELINUX_USE_CURRENT_RANGE=
OLDPWD=/root
SSH_TTY=/dev/pts/1
LC_ALL=C
USER=root
#中間省略部分內容....
MAIL=/var/spool/mail/root
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
PWD=/server/scripts
LANG=zh_CN.UTF-8
SELINUX_LEVEL_REQUESTED=
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
LOGNAME=root
CVS_RSH=ssh
SSH_CONNECTION=192.168.197.149592 192.168.197.133 22
LESSOPEN=||/usr/bin/lesspipe.sh%s
G_BROKEN_FILENAMES=1
_=/bin/env
3.3.3 #當前終端變量
[root@kailescripts]# echo $PS1
[\u@\h \W]\$
3.4局部變量
定義局部變量
局部變量在用戶當前的shell生存期的腳本中使用。例如,局部變量clear取值為clear098,這個值只在用戶當前shell生存期中有意義。如果在shell中啟動另一個進程或退出,局部變量clear值將無效。
普通字符串變量定義
變量名=value
變量名=‘value’
變量名=“value”
shell中變量名及變量內容的要求
·?????一般是字母,數字,下劃線組成,且以字母開頭。如clear,kaile23,clear-training。變量的內容,可以使用單引號或雙引號印起來,或不加引號。
·?????雖然變量可以以下劃線開頭,但類似這種變量都是比較特殊的,都是系統自己用的。我們盡量少用。
[root@kaile?scripts]#?_123=eeee[root@kaile?scripts]#?echo?$_123eeee普通字符串變量定義測試
[root@kaile?scripts]#?a=192.168.1.2[root@kaile?scripts]#?b='192.168.1.2'[root@kaile?scripts]#?c="192.168.1.2"[root@kaile?scripts]#?echo?"a=$a"a=192.168.1.2[root@kaile?scripts]#?echo?"b=$b"b=192.168.1.2[root@kaile?scripts]#?echo?"c=${c}"c=192.168.1.2[root@kaile?scripts]#?a=192.168.1.2-$a[root@kaile?scripts]#?b='192.168.1.2-$a'[root@kaile?scripts]#?c="192.168.1.2-$a"[root@kaile?scripts]#?echo?"a=$a"a=192.168.1.2-192.168.1.2[root@kaile?scripts]#?echo?"b=$b"b=192.168.1.2-$a[root@kaile?scripts]#?echo?"c=${c}"c=192.168.1.2-192.168.1.2-192.168.1.2把一個命令做為變量
[root@kailescripts]# ls
clear.sh? clear_log.sh
[root@kaile scripts]# CMD=`ls`
[root@kailescripts]# echo $CMD
clear.shclear_log.sh
[root@kailescripts]# CMD1=$(pwd)
[root@kailescripts]# echo $CMD1
/server/scripts
變量名=`ls`?<==反引號變量名=$(ls)小結:
1)CMD=ls的ls兩側的符號是鍵盤tab鍵上面的,不是單引號。
2)在變量名前加$,可以取得此變量的值,使用echo或printf命令可以顯示變量的值,$A和$(A)寫法不同,效果一樣,推薦后面的寫法。
3)${WEEK}DAY若變量和其他字符組成新的變量就必須給變量加上大括號{}.
4)養成將所有字符串變量用雙引號括起來使用的習慣,減少編程遇到的怪異錯誤。“$A”和“${A}”
3.5變量名及變量內容定義小結
1.?????????變量名只能由字母,數字,下劃線組成,且以字母開頭。
2.?????????規范的變量名寫法定義:見名知意
a,ClearAge=1 <==每個單詞首字母大寫
b,clear_age=1 <==每個單詞之間用“-”
c,clearAgeSex=1<==駝峰語法:首個單詞字母小寫,其余單詞首字母大寫
3.? =號的知識,a=1中的等號是賦值的意思,比較是不是相等為“==”
4.?????????打印變量,變量名前接$符號,變量名后接字符的時候,要用大括號括起來
[root@kaile ~]# word="big"
[root@kaile ~]# echo ${word}ger
bigger
[root@kaile ~]# echo $wordger
?1.? 注意變量內容引用方法,一般為雙引號,簡單連續字符可以不加引號,希望原樣輸出,使用單引號。
2.? 變量內容是命令,要用反引號``或者$()把變量括起來使用
Shell腳本可以提高我們日常工作的效率 。?
學好一門編程語言 ?多練 多敲 多思考 再練 在思考 。。。。。
轉載于:https://blog.51cto.com/kaile/1918675
總結
- 上一篇: @ConfigurationProper
- 下一篇: Linux Ubuntu常用命令