2013-06-05 37 views
7

我正在編寫一個.sh腳本,它將在某些時候將用戶的shell更改爲/ bin/zsh。命令如下課程:確定當前用戶的shell

chsh -s /bin/zsh 

然而,這要求用戶輸入的密碼,我想如果當前用戶的shell是不是已經/bin/zsh只執行它。爲此,我需要一個能夠讓我知道當前shell的命令,並將它與"/bin/zsh"或類似內容進行比較。我發現有一個c getusershell函數,但是沒有辦法從shell腳本中知道這一點嗎?

更新:對不起,我的意思是用戶指定的shell作爲他的首選shell。所以是的,在/etc/passwd中指定的那個。這背後的邏輯是,腳本將要將用戶的首選shell更改爲zsh,並且我只希望腳本首先檢查它是不是zsh。

+2

grep/etc/passwd來獲取用戶的「官方」shell。但請注意,它們可能不會從該shell實際運行該腳本。他們可以很好地登錄使用(說)短跑,手動運行bash,並已切換到korn外殼,等等...... –

+3

@MarcB如果我們只支持Linux,最好使用'getent passwd「$ USER」'因爲getent將搜索在nsswitch(LDAP,NIS等)中配置的whahtever,而greet「/ etc/passwd」只能在配置爲_use_/etc/passwd的系統上運行。 –

+1

「當前shell」是什麼意思?當前在'/ etc/passwd'中指定的那個還是當前正在執行的那個? – Jens

回答

14

$SHELL返回當前用戶的外殼:

$ echo $SHELL 
/bin/zsh 
+0

現在好吧,我以前不知道'$ SHELL',我感到很傻。非常感謝! – Ernesto

+2

請注意,如果用戶沒有啓動或執行不同的shell,'$ SHELL'只與'/ etc/passwd'中的相同。尋找登錄shell的防彈方法是通過查看'/ etc/passwd'。 – Jens

+0

@Jens,沒有子彈的證據。用戶條目可能不在/ etc/passwd中,例如NIS,NIS +或LDAP。 – jlliagre

2
$ awk -F: '$1 == "myusername" {print $NF}' /etc/passwd 
/bin/zsh 

或者,如果你有shell變量var用戶名:

awk -F: -v u=$var '$1 == u {print $NF}' /etc/passwd 

這是假定/etc/passwd是本地完成(而不是作爲NIS服務;看到你​​和各自的手冊頁)。

+0

這不會得到用戶分配的shell嗎?這個問題要求現在的問題。 –

+0

我認爲「當前shell」是指'/ etc/passwd'中的那個。使用'chsh'將任何其他shell更改爲zsh是沒有意義的。你不能替換正在運行的shell。但是,是的,這個問題不明確。 – Jens

+0

是的,對不起,我的問題還不夠清楚。當我說「當前shell」時,我的意思是用戶目前指定的shell作爲他的首選shell,也就是我即將改爲zsh的那個。 – Ernesto

2

下面的命令會給你當前的shell(在CMD細胞):

ps -p $$ 
+1

這是當前正在執行的shell,可能是也可能不是用戶的登錄shell。 –

0

以下工作:

ps p $$ | awk '{print $5}' 

有時$ SHELL和/ etc/passwd中的值不正確。

+0

這是當前正在執行的shell,可能是也可能不是用戶的登錄shell。 「/ etc/passwd」中的值在什麼意義上是「不正確的」(假設信息實際上來自'/ etc/passwd'文件)? –

+0

如果您的默認shell是bash,並且在bash中鍵入'zsh'。您當前的shell不再是'/ etc/passwd'中顯示的shell。 – cforbish

+0

該OP已經明確指出'/ etc/passwd'(或等價物)中的shell是他感興趣的。 –

4

您不應該假設/etc/passwd是存儲用戶shell的位置。

我這樣做:

getent passwd $(id -un) | awk -F : '{print $NF}' 

編輯:請注意,getent只在Solaris中,BSD系統和基於GNU/Linux的操作系統。

AIX,HP-UX和OS X都有自己的方法做了類似的事情(RESP。lsusers -cpwget -ndscl ...),因此如果這些操作系統必須支持該命令應得到加強。

+0

不幸的是,getent不是POSIX,因此您認爲Solaris,任何BSD或Linux。 – Jens

+0

@Jens的確,這是一個恥辱POSIX錯過了這個命令。 – jlliagre

0
perl -e '@pw = getpwuid $< ; print $pw[8], "\n"' 

這假定Perl安裝,配置正確,並在您$PATH,這是最現代的類Unix系統一個相當安全的賭注。 (這可能是一個更安全的賭注比getent是可用的,或者用戶信息實際存儲在/etc/passwd文件,或者說,$SHELL值沒有被改變。)

$<是當前進程的真實UID 。無論系統使用什麼其他機制(NIS,LDAP),getpwuid()都會從/etc/passwd返回值的數組。該陣列的元素8是用戶的登錄shell。

上面可以稍微縮短爲:

perl -e 'print +(getpwuid $<)[8], "\n"' 

perl -e 'print((getpwuid $<)[8], "\n")' 

爲一元+操作者或額外的括號的原因是相當模糊。