如何在 Linux 上的 Bash 中使用“這裡的文檔”

已發表: 2022-01-29
Linux 計算機系統上的終端窗口。
Fatmawati Achmad Zaenuri/Shutterstock

奇怪的命名為“here documents”讓您可以在 Linux 上的 Bash 腳本中使用輸入/輸出重定向。 它們是自動化您需要在遠程計算機上運行的命令的好方法。

這裡的文件

Linux 中的許多命令都有兩個或三個字母的名稱。 這在一定程度上引起了人們認為 Linux 難以學習且充滿神秘命令的概念。 但是 Linux 中最奇怪的名字之一併不是神秘短的名字之一。 “這裡的文檔”不是文檔,“這裡”指的是什麼也不是很清楚。

它們是一個相對晦澀的構造,但它們很有用。 當然,這是 Linux,所以給貓剝皮的方法不止一種。 此處文檔提供的某些功能可以通過其他方式複制。 這些替代方法通常更複雜。 在編程和腳本中,“更複雜”也意味著“更容易出現錯誤”,並且您的代碼更難維護。

此處文檔真正出色的地方在於,您希望從腳本中建立的連接發送到遠程計算機的命令的自動化。 建立連接很容易,但是一旦建立連接,如何將腳本中的命令“泵”到遠程計算機的 shell 中? 這裡的文檔可以讓您非常簡單地做到這一點。

Here文檔的基本原理

此處文檔的慣用表示如下所示:

 命令 << 限製字符串
 .
 .
文本 
數據
變量
.
.
限製字符串
  • COMMAND :這可以是任何接受重定向輸入的 Linux 命令。 請注意, echo命令不接受重定向輸入。 如果您需要寫入屏幕,可以使用cat命令。
  • << :重定向運算符。
  • limit_string :這是一個標籤。 只要它沒有出現在您重定向到命令中的數據列表中,它就可以是您喜歡的任何東西。 它用於標記文本、數據和變量列表的結束。
  • 數據列表:要提供給命令的數據列表。 它可以包含命令、文本和變量。 數據列表的內容一次一行地輸入到命令中,直到遇到 _limit_string。
廣告

您可能會在此處看到使用“EOF”作為限製字符串的文檔示例。 我們不贊成這種做法。 它有效,但“EOF”表示“文件結束”。 除了家庭文檔是腳本文件中最後一件事的罕見情況外,“EOF”被錯誤地使用。

如果您使用引用您正在做的事情的限製字符串,它將使您的腳本更具可讀性。 如果您通過安全外殼 (SSH) 向遠程計算機發送一系列命令,那麼一個名為“_remote_commands”之類的限製字符串將非常有意義。 您不需要以下劃線“ _ ”字符開頭。 我們這樣做是因為它在您的腳本中將它們標記為與眾不同的東西。

簡單的例子

您可以在命令行和腳本中使用此處的文檔。 當您在終端窗口中鍵入以下內容時,每次按“Enter”時都會看到“ > ”行繼續提示。 當您鍵入“_end_of_text”限製字符串並按“Enter”時,網站列表將傳遞給cat,並顯示在終端窗口中。

 貓 << _end_of_text 
極客指南 
評論極客 
生活精明 
精通雲的 IT
心靈反彈
_end_of_text 

這不是最有價值的練習,但它確實表明在整理整個數據列表並遇到限製字符串之前,不會向命令發送任何內容。 在您輸入限製字符串“_end_of_text”並按“Enter”鍵之前, cat命令不會接收任何輸入。

我們可以在腳本中做同樣的事情。 將此示例鍵入或複製到編輯器中,將文件另存為“heredoc-1.sh”,然後關閉編輯器。

 #!/bin/bash

貓 << "_end_of_text"
您的用戶名是:$(whoami)
您當前的工作目錄是:$PWD
你的 Bash 版本是:$BASH_VERSION
_end_of_text

當您閱讀本文時,每次創建腳本時,您都需要使其可執行,然後才能運行。 在每種情況下,使用chmod命令。 將每個示例中的腳本名稱替換為此處使用的腳本名稱。

 chmod +x heredoc-1.sh 

廣告

該腳本包含兩個環境變量$PWD$BASH_VERSION 。 執行腳本時,環境變量名稱被它們的數據值(當前工作目錄和 Bash 版本)替換。

該腳本還對whoami命令使用命令替換。 命令的名稱被其自己的輸出替換。 整個腳本的輸出由 cat 命令寫入終端窗口。 我們通過名稱調用它來運行腳本:

 ./heredoc-1.sh 

如果修改腳本,將 here 文檔第一行的限製字符串用引號“ " ”括起來,則數據列表將逐字傳遞給 here 文檔命令。顯示變量名稱而不是變量值,並且命令替換將不發生。

 #!/bin/bash

貓<<-“_end_of_text”
您的用戶名是:$(whoami)
您當前的工作目錄是:$PWD
你的 Bash 版本是:$BASH_VERSION
_end_of_text
 ./heredoc-1.sh 

處理製表符

默認情況下,數據列表中的製表符將被保留並寫入終端窗口。 複製此示例並將其另存為“heredoc-2.sh”。 使用chmod命令使其可執行。 編輯縮進的行以確保它們在行首有一個或兩個製表符而不是一系列空格。

 #!/bin/bash

貓 << _end_of_text
您的用戶名是:$(whoami)
  您當前的工作目錄是:$PWD
    你的 Bash 版本是:$BASH_VERSION
_end_of_text
 ./heredoc-2.sh 

選項卡被寫入終端窗口。

通過向重定向運算符添加破折號“ - ”,此處的文檔將忽略前導製表符。 將此示例保存為“heredoc-3.sh”並使其可執行。

 #!/bin/bash

貓 <<- _end_of_text
您的用戶名是:$(whoami)
  您當前的工作目錄是:$PWD
    你的 Bash 版本是:$BASH_VERSION
_end_of_text
 ./heredoc-3.sh 

選項卡被忽略。 這可能看起來微不足道,但由於腳本的縮進部分,它是處理前導選項卡的一種巧妙方法。

廣告

循環和其他邏輯結構通常是縮進的。 如果您的 here 文檔包含在腳本的縮進部分中,則在重定向運算符中使用破折號“ - ”可以消除由前導製表符引起的格式問題。

 #!/bin/bash

如果是真的; 然後
  貓 <<- _limit_string
  第 1 行帶有前導製表符。
  第 2 行帶有前導製表符。
  第 3 行帶有前導製表符。
  _limit_string
菲

重定向到文件

與 here 文檔一起使用的命令的輸出可以重定向到文件中。 在此處文檔的第一行中的限製字符串之後使用“ > ”(創建文件)或“ >> ”(如果文件不存在則創建文件,如果存在則附加到文件)重定向運算符。

這個腳本是“heredoc-4.sh”。 它將其輸出重定向到一個名為“session.txt”的文本文件。

 #!/bin/bash

貓 << _end_of_text > session.txt
您的用戶名是:$(whoami)
您當前的工作目錄是:$PWD
你的 Bash 版本是:$BASH_VERSION
_end_of_text
 ./heredoc-4.sh
 貓會話.text 

將輸出傳送到另一個命令

此處文檔中使用的命令的輸出可以通過管道作為另一個命令的輸入。 使用管道“ | ” 運算符位於此處文檔第一行中的限製字符串之後。 我們將把 here document 命令cat的輸出通過管道傳輸到sed中。 我們想用字母“e”替換所有出現的字母“a”。

將此腳本命名為“heredoc-5.sh”。

 #!/bin/bash

貓 << _end_of_text | sed 's/a/e/g'
如何
到
蓋克
_end_of_text
 ./heredoc-5.sh

“Gaak”被更正為“Geek”。

向函數發送參數

與此處文檔一起使用的命令可以是腳本中的函數。

此腳本將一些車輛數據傳遞到函數中。 該函數讀取數據,就好像它是由用戶輸入的一樣。 然後打印變量的值。 將此腳本另存為“heredoc-6.sh”。

 #!/bin/bash

# set_car_details() 函數
set_car_details ()
{
讀作
讀取模型
閱讀 new_used
閱讀delivery_collect
讀取位置
閱讀價格
}

# 將數據傳遞給 set_car_details() 的 here 文檔
set_car_details << _mars_rover_data
美國國家航空航天局
毅力漫遊者
用過的
蒐集
火星(經緯度)77.451865,18.445161
22億
_mars_rover_data

# 獲取車輛詳細信息
迴聲“製作:$make”
迴聲“模型:$模型”
echo "新的或二手的:$new_used"
echo "送貨或收貨:$delivery_collect"
迴聲“位置:$位置”
迴聲“價格\$:$價格”
 ./heredoc-6.sh 

車輛詳細信息被寫入終端窗口。

創建和發送電子郵件

我們可以使用此處的文檔來撰寫和發送電子郵件。 注意,我們可以在重定向操作符前面給命令傳遞參數。 我們使用Linux mail命令通過本地郵件系統向名為“dave”的用戶帳戶發送電子郵件。 -s (主題)選項允許我們指定電子郵件的主題。

此示例形成腳本“heredoc-7.sh”。

 #!/bin/bash

article="這里文檔"

mail -s '工作負載狀態' dave << _project_report
用戶名:$(whoami)
已完成任務:
文章:$article
_項目報告
./heredoc-7.sh 

廣告

此腳本沒有可見的輸出。 但是當我們檢查我們的郵件時,我們會看到這封電子郵件是撰寫、發送和傳遞的。

 郵件

通過 SSH 使用 Here Documents

建立 SSH 連接後,這裡的文檔是一種在遠程計算機上執行某些命令的強大而方便的方法。 如果您在兩台計算機之間設置了 SSH 密鑰,則登錄過程將是全自動的。 在這個快速而骯髒的示例中,系統將提示您輸入遠程計算機上用戶帳戶的密碼。

這個腳本是“heredoc-8.sh”。 我們將連接到名為“remote-pc”的遠程計算機。 該用戶帳戶稱為“dave”。 我們使用-T (禁用偽終端分配)選項,因為我們不需要為我們分配交互式偽終端。

在腳本的“在這裡做一些工作”部分,我們可以傳遞一個命令列表,這些命令將在遠程計算機上執行。 當然,您可以只調用遠程計算機上的腳本。 遠程腳本可以保存您想要執行的所有命令和例程。

我們的腳本——heredoc-8.sh——要做的就是更新遠程計算機上的連接日誌。 用戶帳戶以及時間和日期戳記錄到文本文件中。

 #!/bin/bash

ssh -T [email protected] << _remote_commands

# 在這裡做一些工作

# 更新連接日誌
echo $USER "-" $(date) >> /home/dave/conn_log/script.log
_remote_commands
廣告

當我們運行該命令時,系統會提示我們輸入遠程計算機上帳戶的密碼。

 ./heredoc-8.sh 

顯示有​​關遠程計算機的一些信息,然後我們返回到命令提示符。

遠程計算機上,我們可以使用cat查看連接日誌:

 貓 conn_log/script.log 

每個連接都為我們列出。

相關:如何從 Linux Shell 創建和安裝 SSH 密鑰

奇怪的名字,簡潔的功能

這裡的文檔古怪但功能強大,尤其是在用於向遠程計算機發送命令時。 使用rsync編寫備份例程腳本很簡單。 然後,該腳本可以連接到遠程計算機,檢查剩餘存儲空間,並在空間不足時發送警報電子郵件。

相關:如何使用 rsync 備份你的 Linux 系統