您好,登錄后才能下訂單哦!
這篇文章主要介紹了在Linux Shell中的使用技巧有哪些,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
人們經常使用cut甚至awk只是通過模式或使用分隔符減去字符串的一部分。
另外,許多人使用$ {VARIABLE:start_position:length}進行子字符串bash操作,這非常快。
但是bash提供了一種使用#,##,%和%%來處理文本字符串的強大方法-它稱為bash變量擴展。
使用此語法,您可以在無需執行外部命令的情況下減少模式的需要,因此它將非常快速地工作。
下面的示例顯示了如何使用cut或變量擴展從字符串中獲取第三列(shell),其中用冒號«username:homedir:shell»分隔的值(我們使用*: mask和##命令,這意味著:將所有字符向左剪切,直到找到最后一個冒號為止):
$ STRING="username:homedir:shell" $ echo "$STRING"|cut -d ":" -f 3 shell $ echo "${STRING##*:}" shell
第二個選項不啟動子進程(cut),并且根本不使用管道,這樣可以更快地工作。而且,如果您在管道幾乎不移動的Windows上使用bash子系統,則速度差異會很大。
讓我們看一下Ubuntu上的示例:循環執行我們的命令1000次
$ cat test.sh #!/usr/bin/env bash STRING="Name:Date:Shell" echo "using cut" time for A in {1..1000} do cut -d ":" -f 3 > /dev/null <<<"$STRING" done echo "using ##" time for A in {1..1000} do echo "${STRING##*:}" > /dev/null done
結果
$ ./test.sh using cut real 0m0.950s user 0m0.012s sys 0m0.232s using ## real 0m0.011s user 0m0.008s sys 0m0.004s
差別是幾十倍!
當然,上面的例子太人為了。在實際示例中,我們將不使用靜態字符串,而是要讀取真實文件。對于“ cut ”命令,我們只將/etc /passwd重定向到它。在##的情況下,我們必須創建一個循環并使用內部的' read '命令讀取文件。那么誰將贏得這場案子呢?
$ cat test.sh #!/usr/bin/env bash echo "using cut" time for count in {1..1000} do cut -d ":" -f 7 </etc/passwd > /dev/null done echo "using ##" time for count in {1..1000} do while read do echo "${REPLY##*:}" > /dev/null done </etc/passwd done
結果
還有兩個示例:
在等號后提取值:
$ VAR="myClassName = helloClass" $ echo ${VAR##*= } helloClass
提取括號中的文本:
$ VAR="Hello my friend (enemy)" $ TEMP="${VAR##*\(}" $ echo "${TEMP%\)}" enemy
bash-completion軟件包幾乎是每個Linux發行版的一部分。您可以在/etc/bash.bashrc或/etc/profile.d/bash_completion.sh中啟用它,但是通常默認情況下已啟用它。通常,自動完成是新手首先遇到的Linux Shell上的第一個便捷時刻。
但是并非所有人都使用所有bash補全功能這一事實,在我看來完全是徒勞的。例如,不是所有人都知道,自動完成功能不僅適用于文件名,而且適用于別名,變量名,函數名,甚至適用于某些帶有參數的命令。如果您深入研究自動完成腳本(實際上是shell腳本),甚至可以為自己的應用程序或腳本添加自動完成。
但是,讓我們回到別名。
您無需編輯PATH變量或在指定目錄中創建文件即可運行別名。您只需要將它們添加到配置文件或啟動腳本中,然后在任何位置執行它們即可。
通常,我們在* nix中使用小寫字母表示文件和目錄,因此創建大寫別名非常方便-在這種情況下,bash-completion 幾乎會用單個字母來猜測您的命令:
$ alias TAsteriskLog="tail -f /var/log/asteriks.log" $ alias TMailLog="tail -f /var/log/mail.log" $ TA[tab]steriksLog $ TM[tab]ailLog
對于更復雜的情況,可能您想將個人腳本放入$ HOME / bin。
但是我們在bash中有功能。
函數不需要路徑或單獨的文件。(注意)bash補全也可以與函數一起使用。
讓我們在.profile中創建函數LastLogin (不要忘記重新加載.profile):
function LastLogin { STRING=$(last | head -n 1 | tr -s " " " ") USER=$(echo "$STRING"|cut -d " " -f 1) IP=$(echo "$STRING"|cut -d " " -f 3) SHELL=$( grep "$USER" /etc/passwd | cut -d ":" -f 7) echo "User: $USER, IP: $IP, SHELL=$SHELL" }
在控制臺中(請注意,函數名的首字母大寫以加快bash的完成速度):
$ L[tab]astLogin User: saboteur, IP: 10.0.2.2, SHELL=/bin/bash
如果您在控制臺中的任何命令前放置空格,則它將不會出現在命令歷史記錄中,因此,如果您需要在命令中放置純文本密碼,這是使用此功能的一種好方法—在下面的示例中回顯«hello 2»將不會出現在歷史記錄中:
$ echo "hello" hello $ history 2 2011 echo "hello" 2012 history 2 $ echo "my password secretmegakey" # there are two spaces before 'echo' my password secretmegakey $ history 2 2011 echo "hello" 2012 history 2
它是可選的
您想在git中存儲一些shell腳本以在服務器之間共享它們,或者它可能是應用程序啟動腳本的一部分。并且您希望此腳本將連接到數據庫或執行其他需要憑據的操作。
當然,將憑據存儲在腳本本身中是個壞主意,因為git是不安全的。
通常,您可以使用已經在目標環境上定義的變量,并且腳本本身將不包含密碼。
例如,您可以在具有700個權限的每個環境上創建小腳本,并使用主腳本中的source命令調用它:
secret.sh PASSWORD=LOVESEXGOD myapp.sh source ~/secret.sh sqlplus -l user/"$PASSWORD"@database:port/sid @mysqfile.sql
但這并不安全。
如果其他人可以登錄到您的主機,則他只需執行ps命令并查看帶有整個命令行參數(包括密碼)的sqlplus進程。因此,安全工具通常應該能夠直接從文件中讀取密碼/密鑰/敏感數據。
例如,安全ssh甚至沒有任何選項可以在命令行中提供密碼。但是他可以從文件讀取ssh密鑰(并且可以在ssh密鑰文件上設置安全權限)。
非安全wget具有選項“ --password”,該選項使您可以在命令行中提供密碼。wget一直在運行,每個人都可以執行ps命令并查看您提供的密碼。
另外,如果您有很多敏感數據,并且想通過git控制它,那么唯一的方法就是加密。因此,您只需將每個主密碼以及所有其他可以加密并放入git的數據輸入到每個目標環境。而且,您可以使用openssl CLI界面從命令行使用加密的數據。以下是從命令行進行加密和解密的示例:
文件secret.key包含主密鑰-單行:
$ echo "secretpassword" > secret.key; chmod 600 secret.key
讓我們使用aes-256-cbc加密字符串:
$ echo "string_to_encrypt" | openssl enc -pass file:secret.key -e -aes-256-cbc -a U2FsdGVkX194R0GmFKCL/krYCugS655yLhf8aQyKNcUnBs30AE5lHN5MXPjjSFML
您可以將此加密的字符串放入git或其他任何位置存儲的任何配置文件中-沒有secret.key,幾乎不可能對其進行解密。
要解密執行同一命令,只需將-e替換為-d即可:
$ echo 'U2FsdGVkX194R0GmFKCL/krYCugS655yLhf8aQyKNcUnBs30AE5lHN5MXPjjSFML' | openssl enc -pass file:secret.key -d -aes-256-cbc -a string_to_encrypt
所有人都應該知道grep命令。并且對正則表達式要友好。通常,您可以編寫如下內容:
tail -f application.log | grep -i error
甚至像這樣:
tail -f application.log | grep -i -P "(error|warning|failure)"
但是不要忘記grep有很多很棒的選擇。例如-v,它會還原您的搜索并顯示除“ info”消息以外的所有消息:
tail -f application.log | grep -v -i "info"
其他內容:
選項-P非常有用,因為默認情況下,grep使用相當過時的«基本正則表達式:»,并且-P啟用PCRE,甚至不知道分組。
-i忽略大小寫。
--line-buffered立即解析行,而不是等待到達標準的4k緩沖區(對于tail -f | grep非常有用)。
如果您非常了解正則表達式,則使用--only-matching / -o可以真正實現剪切文本的出色功能。只需比較以下兩個命令以提取myuser的shell:
$ grep myuser /etc/passwd| cut -d ":" -f 7 $ grep -Po "^myuser(:.*){5}:\K.*" /etc/passwd
第二個命令看起來更編譯,但是它只運行grep而不是grep和cut,因此執行時間會更少。
在* nix中,如果刪除應用程序當前正在使用的日志文件,則不能僅刪除所有日志,還可以阻止應用程序在重新啟動之前編寫新日志。
由于文件描述符不是打開文件名而是打開iNode結構,因此應用程序將繼續將文件描述符寫入沒有目錄條目的文件,并且該文件將在應用程序停止后由文件系統自動刪除(您的應用程序可以每次想寫一些東西來避免這種問題時都要打開和關閉日志文件,但這會影響性能)。
因此,如何清除日志文件而不刪除它:
echo "" > application.log
或者我們可以使用truncate命令:
truncate --size=1M application.log
提及,該truncate命令將刪除文件的其余部分,因此您將丟失最新的日志事件。另一個示例如何存儲最后1000行:
echo "$(tail -n 1000 application.log)" > application.log
PS在Linux中,我們有標準的服務rotatelog。您可以將日志添加到自動截斷/旋轉中,也可以使用現有的日志庫來完成(例如Java中的log4j)。
在某些情況下,您正在等待事件結束。例如,當另一個用戶登錄到shell(您連續執行who命令)時,或者某人應該使用scp或ftp將文件復制到您的計算機上時,您正在等待完成(重復ls數十次)。
在這種情況下,您可以使用
watch <command>
默認情況下,將每隔2秒鐘執行一次,且屏幕會預先清除,直到按Ctrl + C。您可以配置執行頻率。
當您要觀看實時日志時,此功能非常有用。
創建范圍非常有用。例如,而不是像這樣:
for srv in 1 2 3 4 5; do echo "server${srv}";done server1 server2 server3 server4 server5
您可以編寫以下內容:
for srv in server{1..5}; do echo "$srv";done server1 server2 server3 server4 server5
您也可以使用seq命令生成格式化范圍。例如,我們可以使用seq創建值,將根據寬度(00、01而不是0、1)自動調整抽動:
for srv in $(seq -w 5 10); do echo "server${srv}";done server05 server06 server07 server08 server09 server10
使用命令替換的另一個示例-重命名文件。要獲取不帶擴展名的文件名,我們使用“ basename ”命令:
for file in *.txt; do name=$(basename "$file" .txt);mv $name{.txt,.lst}; done
甚至還比'%'更短:
for file in *.txt; do mv ${file%.txt}{.txt,.lst}; done
PS實際上,對于重命名文件,您可以嘗試使用具有許多選項的“ 重命名 ”工具。
另一個示例-讓我們為新的Java項目創建結構:
mkdir -p project/src/{main,test}/{java,resources}
結果
我已經提到了multitail來讀取文件并觀看多個實時日志。但是默認情況下未提供該功能,并且安裝某些內容的權限并非始終可用。
但是標準尾巴也可以做到:
tail -f /var/logs/*.log
還讓您記住有關用戶的信息,這些用戶使用'tail -f'別名查看應用程序日志。
多個用戶可以使用“ tail -f”同時觀看日志文件。他們中有些人的會話不太準確。由于某種原因,他們可能會將'tail -f'留在背景中而忘記了。
如果重新啟動應用程序,則有一些正在運行的“ tail -f”進程正在監視不存在的日志文件,該進程可能會掛起幾天甚至幾個月。
通常這不是一個大問題,但不是整齊的。
如果您使用別名來查看日志,則可以使用--pid選項修改此別名:
alias TFapplog='tail -f --pid=$(cat /opt/app/tmp/app.pid) /opt/app/logs/app.log'
在這種情況下,重新啟動目標應用程序時,所有尾部將自動終止。
dd是使用塊和二進制數據的最受歡迎的工具之一。例如,創建1 MB文件并填充零將是:
dd if=/dev/zero of=out.txt bs=1M count=10
但我建議使用fallocate:
fallocate -l 10M file.txt
在支持分配功能(xfs,ext4,Btrfs ...)的文件系統上,fallocate將立即執行,這與dd工具不同。另外,分配是指實際分配塊,而不是創建備用文件。
很多人都知道流行的xargs命令。但是并非所有人都使用以下兩個選項,因此可以極大地改善腳本。
首先-您可以獲得非常長的參數列表,并且可能超過命令行長度(默認情況下?4 kb)。
但是您可以使用-n選項限制執行,因此xargs將多次運行命令,一次發送指定數量的參數:
$ # lets print 5 arguments and send them to echo with xargs: $ echo 1 2 3 4 5 | xargs echo 1 2 3 4 5 $ # now let’s repeat, but limit argument processing by 3 per execution $ echo 1 2 3 4 5 | xargs -n 3 echo 1 2 3 4 5
來吧 處理長列表可能需要很多時間,因為它在單個線程中運行。但是,如果我們有幾個核心,我們可以告訴xargs并行運行:
echo 1 2 3 4 5 6 7 8 9 10| xargs -n 2 -P 3 echo
在上面的示例中,我們告訴xargs處理3個線程中的list;每個線程每次執行將接受并處理2個參數。如果您不知道自己有多少個內核,請使用“ nproc ” 進行優化:
echo 1 2 3 4 5 6 7 8 9 10 | xargs -n 2 -P $(nproc) echo
有時您需要等待幾秒鐘。或等待用戶輸入以下內容:
read -p "Press any key to continue " -n 1
但是您只需添加超時選項以讀取命令,腳本就會暫停指定的秒數,但是在交互執行的情況下,用戶可以輕松地跳過等待。
read -p "Press any key to continue (auto continue in 30 seconds) " -t 30 -n 1
因此,您只需忘記睡眠命令即可。
我懷疑并不是所有的花招看起來都很有趣,但是在我看來,有十二個數字是可以填寫的好數字。
感謝你能夠認真閱讀完這篇文章,希望小編分享的“在Linux Shell中的使用技巧有哪些”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。