SHELL腳本攻略(學習筆記)--1.4 變數(基礎)

来源:http://www.cnblogs.com/f-ck-need-u/archive/2017/07/24/7229381.html
-Advertisement-
Play Games

本文目錄: 1.4.1 環境變數 1.4.2 普通變數 1.4.3 修改變數的生命周期和作用域 1.4.4 獲取變數的長度 1.4.5 declare聲明變數 1.4.6 位置變數和特殊變數 1.4.7 shift輪替變數 1.4.8 shell其它基礎 1.4.9 變數的切分、提取和替換 變數存在 ...



本文目錄:

1.4.1 環境變數

1.4.2 普通變數

1.4.3 修改變數的生命周期和作用域

1.4.4 獲取變數的長度

1.4.5 declare聲明變數

1.4.6 位置變數和特殊變數

1.4.7 shift輪替變數

1.4.8 shell其它基礎

1.4.9 變數的切分、提取和替換


變數存在於記憶體中。假設變數str,設置或修改變數屬性時,不帶$號,只有引用變數的值時才使用$號。也就是說在記憶體中,標記變數的變數名稱是str,而不是$str

1.4.1 環境變數

環境變數就是運行在"環境"上下文的,在這個上下文都可以引用。例如,常見的cd、ls等命令嚴格來說應該使用絕對路徑如/bin/ls來執行,由於/bin目錄加入到了PATH環境變數中,系統自己會去尋找PATH下的路徑是否有該命令。

環境變數常用大寫字母表示。常見的環境變數有HOSTNAME、SHELL、HISTSIZE、USER、PATH、PWD、LANG、HOME、LOGNAME。分別表示當前主機名、SHELL的路徑即bash的類型、history保存多少記錄、當前用戶名、自動搜索路徑、當前目錄、使用的語系(臨時修改語系時就改這個變數)、當前用戶的家目錄、當前登錄的用戶。

使用env或者export可以查看當前用戶的環境變數。

[root@xuexi ~]# env

XDG_SESSION_ID=411
HOSTNAME=xuexi.longshuai.com
TERM=linux
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=172.16.10.1 10171 22
QTDIR=/usr/lib64/qt-3.3
QTINC=/usr/lib64/qt-3.3/include
SSH_TTY=/dev/pts/0
QT_GRAPHICSSYSTEM_CHECKED=1
USER=root
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
MAIL=/var/spool/mail/root
PATH=/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/sersync:/root/bin
PWD=/root
LANG=en_US.UTF-8
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
LOGNAME=root
QTLIB=/usr/lib64/qt-3.3/lib
SSH_CONNECTION=172.16.10.1 10171 172.16.10.3 22
LESSOPEN=||/usr/bin/lesspipe.sh %s
XDG_RUNTIME_DIR=/run/user/0
_=/usr/bin/env

使用echo可以輸出變數的值。

[root@xuexi ~]# echo $PATH 
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

例如,在PATH環境變數中新加入一個目錄/usr/local/mysql/bin。

[root@xuexi tmp]# PATH=/usr/local/mysql/bin:$PATH

這裡也能看到兩個PATH第一個沒使用$,第二個使用了。當對變數本身進行操作,則不使用$,當對變數值進行操作,則使用$

1.4.2 普通變數

腳本語言是弱類型的語言,變數通常不需要特地聲明甚至不需要初始化,在腳本運行時由解釋器進行解釋運算,解釋器知道變數在什麼時候是什麼類型,所以直接賦值使用即可。bash中,變數預設都是字元串類型,不論是否使用引號賦值,都以字元串方式存儲。

變數賦值方式:str=value,其實是set str=value,省略了set關鍵字。註意等號左右沒有空格。如果有空格就是進行比較運算符的比較運算了。

變數引用方式:$str或者${str},例如echo "the var is ${str}"。

[root@xuexi tmp]# str='Hello World!'

[root@xuexi tmp]# echo "We will say ${str}"
We will say Hello World! 

釋放變數:unset str,註意變數名前不加首碼$。

[root@xuexi ~]# unset str

查看所有的變數:不接任何參數的set或者declare命令,輸出結果中包含了普通變數和環境變數。

定義只讀變數:readonly str。這時將無法修改變數值也無法unset變數,只有重新登錄shell才能繼續使用只讀變數。

臨時將普通變數升級為環境變數:export str或者賦值時export str="value",這樣$str就可以在當前shell和子shell中使用,但是退出腳本或者重新登錄shell都會取消export效果。

[root@xuexi ~]# str='Hello World!';echo $str
Hello World!

[root@xuexi ~]# bash            # 開啟子shell
[root@xuexi ~]# echo ${str}     # 子shell中查看變數結果發現沒有該變數。

在子shell中查看變數,結果竟然發現沒有該變數。這是因為$str的作用域只在當前shell,要想在子shell中也能引用普通變數,則需要使用export升級為環境變數。

[root@xuexi ~]# exit   # 退出子shell

[root@xuexi ~]# export str # 回到父shell升級該變數

[root@xuexi ~]# bash

[root@xuexi ~]# echo $str
Hello World!

1.4.3 修改變數的生命周期和作用域

普通的變數在腳本結束或退出登錄後就失效,並且只對當前shell有效,其他用戶和當前用戶的子shell都無法使用。

使用export可以升級為臨時局部的環境變數,只對當前用戶的當前shell和子shell有效,退出腳本和退出登錄後也失效。

如果想要設置永久的且全局的變數,一種方法是將變數的設置語句放入到/etc/profile文件中,因為每個用戶登錄時,都會調用該文件並執行其中的語句。如果想立即載入此文件中的配置使得臨時添加的設置立即生效,只需source該文件即可。

[root@xuexi ~]# source /etc/profile

/etc/profile文件是bash的全局配置文件,還有每個用戶的配置文件~/.bash_profile,此文件中的變數將只對對應的用戶生效。

此外,還有幾個配置bash環境配置文件,具體的見bash環境配置流程

1.4.4 獲取變數的長度

在使用${}方式引用變數時,變數名前加上#就可以查看該變數的字元長度。空格也算入長度。例如:

[root@xuexi ~]# echo ${#str}
12

[root@xuexi ~]# echo ${#PATH}
92

1.4.5 declare聲明變數

declare [+/-][選項] 變數名

選項說明:

-/+:給變數設定類型屬性,取消給變數設定的類型屬性

-i:聲明為整型

-x:聲明為環境變數

-p:顯式指定變數被聲明的類型

例如,聲明一個環境變數declare -x str,取消該變數declare +x str。

1.4.6 位置變數和特殊變數

$?:上一條代碼執行的回傳指令,回傳0表示標準輸出,即正確執行,否則為標準錯誤輸出。

$$:表示當前登錄的shell的PID。

$!:後臺運行的最後一個進程PID。

$#:統計參數的個數。

$@:所有單個參數,如"a""b""c""d"。

$*:所有參數的整體,如“abcd”。

$0:腳本名。

$1……$n:參數位置。

使用下麵的腳本來驗證位置變數和特殊變數。

root@xuexi tmp]# vim var.sh
#!/bin/bash

# 測試各種變數的作用,包括預定義和自定義變數
echo '$?:'$?
echo '$$:'$$
echo '$!:'$!
echo '$#:'$#
echo '$@:'$@
echo '$*:'$*
echo '$0:'$0
echo '$1:'$1
echo '$2:'$2
echo '$3:'$3
echo '$4:'$4

使用5個參數來運行該腳本。

[root@xuexi tmp]# sh ./var.sh a b c d e
$?:0
$$:6089
$!:
$#:5
$@:a b c d e
$*:a b c d e
$0:./var.sh
$1:a
$2:b
$3:c
$4:d

1.4.7 shift輪替變數

使用shift [N]可以指定參數輪替,每執行一次shift N就踢掉N個參數,預設N為1。

例如在腳本中:

echo $1   # # 輸出第一個參數值
shift 2   # # 踢掉前兩個參數,第三個參數變成$1
echo $1   # # 此時$1的值為第三個參數的值
shift     # # 又踢掉一個參數,第四個參數變成$1
echo $1   # # 輸出第四個參數

1.4.8 shell其他基礎

1、變數中字元的長度:${#VARNAME}

2、變數賦值等:

${parameter:-word}:如果parameter為空或未定義,則變數展開為“word”;否則展開為parameter的值;

${parameter-word}:和${parameter:-word}幾乎等價,除了parameter設置了但為空時,變數的結果將是null,而非word。在/etc/init.d/httpd中有此用法。

${parameter:+word}:如果parameter為空或未定義,不做任何操作,即仍然為空;否則展開為“word”值;

${parameter:=word}:如果parameter為空或未定義,則變數展開為“word”,否則為parameter自身;

${parameter:offset}:取子串,從offset處的後一個字元開始取到最後一個字元;

${parameter:offset:length}:取子串,從offset處的後一個字元開始,取lenth長的子串;

其中${parameter:-word}最常用,最後兩個是截取字元串的,偶爾也會用到。

3、腳本配置文件

配置文件中的變數值可以在腳本中被使用

要在腳本中調用配置文件,直接使用source config_file或“.  config_file”

服務啟動腳本支持配置文件:/etc/sysconfig/服務腳本同名的配置文件

4、局部變數,在函數中定義局部變數使其不影響函數外的同名變數

local VAR_NAME=

5、命令mktemp創建臨時文件或目錄

mktemp [-d] /tmp/file.XX # X指定越多,隨機生成的尾碼就越長,其中-d表示創建臨時目錄。

例如:

[root@xuexi ~]# mktemp haha.XXX
haha.oOe

[root@xuexi ~]# mktemp -d haha.XXX
haha.npz

[root@xuexi ~]# touch haha.npz/A.txt

1.4.9 變數的切分、提取和替換

其實是對變數實現的功能,只是使用文件名的說法比較典型,且容易理解它的用途。

例如,將文件名“Linux.docx.jpg”存放到變數file_name中,然後執行從左向右或從右向左的刪除或貪婪刪除。

[root@xuexi tmp]# file_name="Linux.docx.jpg"
[root@xuexi tmp]# file_name_greedy=${file_name%%.*}
[root@xuexi tmp]# file_name_nongreedy=${file_name%.*}
[root@xuexi tmp]# extention_name_greedy=${file_name##*.}
[root@xuexi tmp]# extention_name_nongreedy=${file_name#*.}

[root@xuexi tmp]# echo -e "${file_name_greedy}\n${file_name_nongreedy}\n${extention_name_greedy}\n${extention_name_nongreedy}"
Linux
Linux.docx
jpg
docx.jpg

${var%%.*}和${var%.*}中的“%%.*”表示從右向左匹配“.*”並刪除,由於Linux.docx.jpg有兩種符合條件的匹配:“.jpg”和“.docx.jpg”,所以使用兩個%%表示貪婪刪除,即刪除最長匹配“.docx.jpg”。可以使用一個%表示非貪婪刪除,表示刪除最短的匹配即“.jpg”。

${var##*.}和${var#*.}中的“##*.”表示從左向右匹配“*.”並執行貪婪刪除,即刪除“Linux.docx.”,同理“#*.”表示非貪婪刪除,即刪除“Linux.”。

除了刪除,還可以實現提取和替換的功能。

[root@xuexi tmp]# echo "${file_name:0:5}"   # 提取第0個位元組後的5個位元組,即1-5位元組
Linux

[root@xuexi tmp]# echo "${file_name:6:4}"   # 提取第6個位元組後的4個位元組,即第7、89、10位元組
docx

[root@xuexi tmp]# echo "${file_name/jpg/pdf}"   # 非貪婪替換jpg為pdf,即只替換從左向右的第一個
Linux.docx.pdf

[root@xuexi tmp]# echo "${file_name//jpg/pdf}"  # 貪婪替換jpg為pdf,即所有的jpg都替換為pdf
Linux.docx.pdf

不錯的功能是替換。有時候想要刪除PATH環境變數中的某個路徑,可以使用變數替換的功能,似乎沒法使用變數切分來實現。例如:

[root@toystory php]# echo $A
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/apache/bin:/usr/local/mysql:/usr/local/apache/bin

註意,由於可能多次讀取了配置文件,導致PATH中出現了重覆的路徑。現在想刪除其中一個路徑。使用下麵的命令就可以實現路徑刪除,註意其中使用了轉義符號,並且變數替換的替換值留空了表示刪除前面匹配的部分。

[root@toystory php]# B=${A/:\/usr\/local\/apache\/bin/}

[root@toystory php]# echo $B
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/mysql:/usr/local/apache/bin

 

回到系列文章大綱:http://www.cnblogs.com/f-ck-need-u/p/7048359.html

轉載請註明出處:http://www.cnblogs.com/f-ck-need-u/p/7229381.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • expr命令可以實現數值運算、數值或字元串比較、字元串匹配、字元串提取、字元串長度計算等功能。它還具有幾個特殊功能,判斷變數或參數是否為整數、是否為空、是否為0等。 先看expr命令的info文檔info coreutils 'expr invocation'的翻譯。 下麵將使用示例來介紹expr的 ...
  • 原文發表於cu:2016-03-11 參考文檔: 一.環境 OS CentOS6.7 x86_64 網路 Sever:192.168.1.254 Client:192.168.1.100 二.安裝與配置 1. 安裝 使用yum安裝即可:yum install vsftpd -y 2. 軟體模塊 3. ...
  • sed編輯器被稱作流編輯器(stream editor),和普通的互動式文本編輯器恰好相反。在互動式文本編輯器中(比如vim),你可以用鍵盤命令來互動式的插入、刪除或者替換數據中的文本。流編輯器則會自愛編輯器處理數據之前基於預習提供的一組規則來編輯數據流。 sed編輯器可以根據命令來處理數據流中的數 ...
  • 大話命令之—ss ss是Socket Statistics的縮寫。顧名思義,ss命令可以用來獲取socket統計信息,它可以顯示和netstat類似的內容。 優勢: (1)顯示更多更詳細的有關TCP和連接狀態的信息,(2)比netstat更快速更高效。 1 格式 格式:ss [option]… [f ...
  • grep簡介 grep 是一種強大的文本搜索工具,它能使用正則表達式搜索文本,並把匹配的行列印出來。通常grep有三種版本grep、egrep(等同於grep -E)和fgrep。egrep為擴展的grep,fgrep則為快速grep(固定的字元串來對文本進行搜索,不支持正則表達式的引用但是查詢極為 ...
  • 進入vi的命令 vi filename :打開或新建文件,並將游標置於第一行首 vi +n filename :打開文件,並將游標置於第n行首 vi + filename :打開文件,並將游標置於最後一行首 vi +/pattern filename:打開文件,並將游標置於第一個與pattern匹配 ...
  • 前言 在安裝後hadoop之後,接下來需要安裝的就是Spark。 scala 2.11.7下載與安裝 具體步驟參見 "上一篇博文" Spark下載 為了方便,我直接是進入到了/usr/local文件夾下麵進行下載 Spark安裝之前的準備 文件的解壓與改名 為了我後面方便配置 ,在這裡我把文件夾的名 ...
  • 回到目錄 一般地,我們在VS里添加了一個解決方案之後,會更新模塊或者業務添加多個api,web項目,這類似於最近說的微服務,而我們的docker-compose與微軟體正好有了一種默契,當你為你的解決方案添加docker支持之後,你會發佈有個docker-compose出現了,它會把所有可以發佈的項 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...