2014-04-29 47 views
11

是否有寫下面的命令更幹法(將會把他們在bash shell腳本):更清潔的方式來寫入多個sed命令?

sudo sed -i 's/^#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config 
sudo sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config 

sudo sed -i 's/^#PermitEmptyPasswords yes/PermitEmptyPasswords no/' /etc/ssh/sshd_config 
sudo sed -i 's/PermitEmptyPasswords yes/PermitEmptyPasswords no/' /etc/ssh/sshd_config 

sudo sed -i 's/^#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config 
sudo sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config 

sudo sed -i 's/^#X11Forwarding yes/X11Forwarding no/' /etc/ssh/sshd_config 
sudo sed -i 's/X11Forwarding yes/X11Forwarding no/' /etc/ssh/sshd_config 
+1

是的。變量:p – keyser

+0

和文件。並使用sed匹配表達式。試試「man sed」。 –

+0

你也可以使用for循環和列表,因爲你總是訪問同一個文件。該列表將包含您所有不同的替換字符串。 – dboals

回答

12

由於要匹配的模式是相似的,你可以使用4個字符串的替代方式並捕獲它。在字符串的開始處使#可選。

下面將結合這些成一個:

sed -i -r 's/^#?(PermitRootLogin|PermitEmptyPasswords|PasswordAuthentication|X11Forwarding) yes/\1 no/' /etc/ssh/sshd_config 

如果你的的sed版本不支持擴展的正則表達式,你可以說:

sed -i 's/^#\{0,1\}\(PermitRootLogin\|PermitEmptyPasswords\|PasswordAuthentication\|X11Forwarding\) yes/\1 no/' /etc/ssh/sshd_config 
+0

@keyser如果沒有'-r','|'和圓括號就不是特殊的,即你需要逃避這些。 – devnull

+0

明白了,謝謝。我的sed沒有它:p – keyser

+1

@keyser添加了一個不帶'-r'的變體。 – devnull

3

您可以使用-e

sudo sed -i -e 'first_command' -e 'second command' ... -e 'last command' /etc/ssh/sshd_config 
+1

+1投票取消刪除你的好答案。 –

3

就像我說的你也可以使用for循環。

 
#!/bin/bash 

FILE='/etc/ssh/sshd_config' 
REPLACE_STRINGS=('s/^#PermitRootLogin yes/PermitRootLogin no/' 's/PermitRootLogin yes/PermitRootLogin no/' 's/^#PermitEmptyPasswords yes/PermitEmptyPasswords no/' 's/PermitEmptyPasswords yes/PermitEmptyPasswords no/' 's/^#PasswordAuthentication yes/PasswordAuthentication no/' 's/PasswordAuthentication yes/PasswordAuthentication no/' 's/^#X11Forwarding yes/X11Forwarding no/' 's/X11Forwarding yes/X11Forwarding no/') 


for i in "${REPLACE_STRINGS[@]}" 
{ 
    sudo sed -i "$i" $FILE 
} 
+0

關於唯一有利於它的是它確實有效。否則,它不能被推薦。 –

+0

我冒昧地在你的答案中解決了一些問題。如果您有任何異議,請隨時恢復。 – devnull

+0

這不如使用單個'sed'調用。 – tripleee

10

無論使用多-e 'sed-command'論點的sed一個調用:

sudo sed -i.bak \ 
     -e 's/^#PermitRootLogin yes/PermitRootLogin no/' \ 
     -e 's/PermitRootLogin yes/PermitRootLogin no/' \ 
     -e 's/^#PermitEmptyPasswords yes/PermitEmptyPasswords no/' \ 
     -e 's/PermitEmptyPasswords yes/PermitEmptyPasswords no/' \ 
     -e 's/^#PasswordAuthentication yes/PasswordAuthentication no/' \ 
     -e 's/PasswordAuthentication yes/PasswordAuthentication no/' \ 
     -e 's/^#X11Forwarding yes/X11Forwarding no/' \ 
     -e 's/X11Forwarding yes/X11Forwarding no/' \ 
     /etc/ssh/sshd_config 

或者創建一個腳本文件,sed.script,包含命令:

s/^#PermitRootLogin yes/PermitRootLogin no/ 
s/PermitRootLogin yes/PermitRootLogin no/ 
s/^#PermitEmptyPasswords yes/PermitEmptyPasswords no/ 
s/PermitEmptyPasswords yes/PermitEmptyPasswords no/ 
s/^#PasswordAuthentication yes/PasswordAuthentication no/ 
s/PasswordAuthentication yes/PasswordAuthentication no/ 
s/^#X11Forwarding yes/X11Forwarding no/ 
s/X11Forwarding yes/X11Forwarding no/ 

,然後運行sed用該文件:

sudo sed -i.bak -f sed.script /etc/ssh/sshconfig 

我已經爲-i選項添加了備份擴展。如果您先編輯主要配置文件而無需先備份副本,那麼您比我更勇敢! (這也是必要的,如果你在Mac OS X或BSD工作; sed有需要與-i的擴展。)

+1

您可以使用'#\?'將命令數減半,或者,如果您的'sed'方言不支持,可能' #*'。 – tripleee

+0

@tripleee:是的,有些方法可以修改正則表達式,包括使用'^#\ {0,1 \}',但有時候,讓人們以更簡單,更詳細的方式編寫替代命令會更容易這會爲他們帶來更可靠的腳本。隨着他們對更復雜的正則表達式變得更加舒適,他們可以減少腳本的內容。但是知道'sed'可以在腳本文件上運行或者有多個'-e'參數(或者一個多行的'-e'參數)是這裏的關鍵信息。 –

+0

是的,這是正確的。我想知道爲什麼@fedorqui選擇使用'-e'來刪除答案。 – devnull

1

你可以把你的sed命令在一個外部文件:

sudo sed -i -f commands.sed /etc/ssh/sshd_config 

commands.sed: 
s/#*PermitRootLogin yes/PermitRootLogin no/ 
s/#*PermitEmptyPasswords yes/PermitEmptyPasswords no/ 
s/#*PasswordAuthentication yes/PasswordAuthentication no/ 
s/#*X11Forwarding yes/X11Forwarding no/ 

您還可以嵌入在bash腳本一個多sed腳本:

#!/bin/bash 

sudo sed -i ' 
    s/#*PermitRootLogin yes/PermitRootLogin no/ 
    s/#*PermitEmptyPasswords yes/PermitEmptyPasswords no/ 
    s/#*PasswordAuthentication yes/PasswordAuthentication no/ 
    s/#*X11Forwarding yes/X11Forwarding no/ 
' /etc/ssh/sshd_config 
0

在標準的UNIX(wher sed的是POSIX,而不是GNU)

sed -e 's/^#PermitRootLogin yes/PermitRootLogin no/;s/PermitRootLogin yes/PermitRootLogin no/;s/^#PermitEmptyPasswords yes/PermitEmptyPasswords no/;s/PermitEmptyPasswords yes/PermitEmptyPasswords no/;s/^#PasswordAuthentication yes/PasswordAuthentication no/;s/PasswordAuthentication yes/PasswordAuthentication no/;s/^#X11Forwarding yes/X11Forwarding no/;s/X11Forwarding yes/X11Forwarding no/' /etc/ssh/sshd_config > /tmp/sshd_config 
cat /tmp/sshd_config > /etc/ssh/sshd_config 
rm /etc/ssh/sshd_config 

normaly它的確定,但線有時定義開始與#餘萬字,並有時無的地方規範,這樣一個PermitRootLogin替補也改變SpecialPermitRootLogin

0

懶惰,但我只是這樣做:

sed -Ei 's/.*PermitRootLogin yes|#PermitRootLogin no/PermitRootLogin no/g' /etc/ssh/sshd_config 
sed -Ei 's/.*PermitEmptyPasswords yes|#PermitEmptyPasswords no/PermitEmptyPasswords no/g' /etc/ssh/sshd_config 
sed -Ei 's/.*PasswordAuthentication yes|#PasswordAuthentication no/PasswordAuthentication no/g' /etc/ssh/sshd_config 
sed -Ei 's/.*X11Forwarding yes|#X11Forwarding no/X11Forwarding no/g' /etc/ssh/sshd_config 

〜SimonTek

0

只是一個小評論。

美麗的解決方案建議here (from ask Ubuntu)

而是在單行兩次寫相同的字,我們可以修改它作爲

sed -i '/^#PermitRootLogin/s/yes/no/' /etc/ssh/sshd_config 

這種方法會減少基礎上錯別字的錯誤。