Bash

用於 scp 解釋波浪號 (~) 的 Bash 腳本太快了

  • August 27, 2014

所以,我剛剛開始了一個新的 C++ 類,它要求我在 Linux 環境中程式。我的機器上沒有安裝 Linux,但我有 OS X,我可以通過 ssh 進入學校實驗室的 linux 機器(這是更可取的,因為我的程式碼必須在實驗室機器上編譯和執行,無論是否不是它在我的機器上工作)。如果你不能在這個問題的結尾說出來,我對 Linux 並不是非常熟悉。

我經常需要將我下載到本地機器上的文件放到遠端機器上,編輯它們以製作程序,然後將它們放回我的本地機器上以將它們上傳到我們的保管箱。我厭倦了打字

scp -P xx user@remote.host.com:~/filename filename

,決定做一個別名來做這件事。就在那時我發現別名不能處理這種事情,所以我決定改寫一個 shell 腳本。這是我所擁有的:

#!/bin/bash

# Author: me
# Created 26 August 2014
# transfers a file from remote machine to current directory in local machine
# keeps same filename

location="$1"
# name gets just the part of the path after the last slash
# ie the filename
name="$(echo "$1" | sed -n -e 's/^.*\///p')"
# echo "$location"
# echo "$name"
scp -P xx user@remote.host.com:"$location" "$name"

從理論上講,我只需鍵入get ~/path/to/filename,它就會從遠端主機獲取文件並將其(使用相同的文件名)複製到本地機器上的目前目錄中。

該 scp 命令,如果從命令行執行,效果很好。當我將它粘貼在 shell 腳本中時,它會中斷。它給了我錯誤:No such file or directory

經過大量測試(您可以在那裡看到一些註釋掉的調試輸出)和研究,我發現外殼在將其發送到腳本~ 之前正在擴展(嗯,這是我根據我發現的關於 glob 的猜測) . 然後我的腳本在本地機器的主文件夾而不是遠端機器的主文件夾的路徑中查找文件。我如何讓它停止這樣做?

我在輸入這個問題時意識到,當我執行命令時我可能只需要一些引號……但我真的不想這樣做。我可以以某種方式解決這個問題而不必輸入get "~/filename",因為必須輸入這些引號真的很煩人。

抱歉,如果有很多無關資訊,但我認為太多總比太少好。謝謝!

PS:我已經找到關於配置 ssh 的內容。雖然有用,但我仍然需要輸入兩次確切的文件名,這不允許我像我想的那樣懶惰。

預設情況下,scp遠端路徑是相對於主目錄解釋的,因此您根本不需要~

scp user@remote.host.com:some/file/name filename

some/file/name將從主目錄下載user並保存在filename本地。如果要在遠端伺服器上使用絕對文件路徑,請以/:開頭scp host:/etc/passwd passwd

嚴格來說,您的伺服器可能會以不同的方式解釋事物。在這種情況下,您可以將~其放入您的腳本中,而不是每次都在命令行上重複它(盡可能地懶惰!):

scp user@remote.host.com:~/"$location" "$name"

這樣你的 shell 就永遠沒有機會解釋它。(也可以~在命令行中引用 :\~'~',但這比必要的工作要多。)不過,我想上面的第一種方法會起作用。


name關於變數的另一個說明。您說您希望它只是基本文件名。有一個用於該確切目的的命令,basename命令

name="$(basename "$location")"

這比通過sed.

引用自:https://unix.stackexchange.com/questions/152349