shの代わりにsudoフォークbashを作成する方法は?

shの代わりにsudoフォークbashを作成する方法は?

~によると須藤(8):

Process model 

sudoは、コマンドを実行するときにfork(2)を呼び出し、上記のように実行環境を設定し、サブプロセスでexecveシステムコールを呼び出します。

また、フォークされたサブプロセスがsh

したがって、コマンドがいくつかのbash関連コマンド(例えばsourceそのコマンド)を含むbashスクリプトである場合、sh正しく実行されません。たとえば、

%猫/tmp/wibble
何かソース
%ls -l /tmp/wibble
-rwxr-xr-x ユーザー 1人 user17 8月24日 08:32 /tmp/wibble
%パスワードルートを取得する
ルート:x:0:0:ルート:/ルート:/bin/bash
% /tmp/スイング
/tmp/wibble: 1: /tmp/wibble: ソース: 見つかりません
% /bin/bash /tmp/wibble ~ [pts/3.4028.1]
/tmp/wibble: 行1: 何か: そのファイルやディレクトリはありません。
% /bin/dash /tmp/wibble
/tmp/wibble: 1: /tmp/wibble: ソース: 見つかりません
% /bin/sh /tmp/wibble
/tmp/wibble: 1: /tmp/wibble: ソース: 見つかりません
%エコ$ SHELL
/bin/zsh
% sudo /tmp/wibble
/tmp/wibble: 1: /tmp/wibble: ソース: 見つかりません
% sudo -s /tmp/wibble
/tmp/wibble: 1: /tmp/wibble: ソース: 見つかりません
% sudo -i /tmp/wibble
/tmp/wibble: 行1: 何か: そのファイルやディレクトリはありません。
% エクスポート SHELL=/bin/bash
% sudo /tmp/wibble
/tmp/wibble: 1: /tmp/wibble: ソース: 見つかりません
% sudo -s /tmp/wibble
/tmp/wibble: 行1: 何か: そのファイルやディレクトリはありません。
% sudo -i /tmp/wibble
/tmp/wibble: 行1: 何か: そのファイルやディレクトリはありません。
%

-s通常、この問題を解決するために前の例のようにオプションを追加できますが、デフォルトが使用されているsudo理由を知りたいです。これを別のシェルで構成できますか?sudosh

答え1

スクリプトが#!適切な-lineで始まることを確認してください。

スクリプトが実行可能で、たとえば次のように始まる場合

#!/bin/bash

(またはシステムへのすべてのパスbash)の後にスクリプトが続きます。〜する/bin/bashsudo scriptと入力すると、Pythonスクリプトは最初の行がとして解釈される/usr/bin/pythonかのように解釈されます#!/usr/bin/python

shシェルbashや他のシェルに関する質問はここでは興味深いものではありません。一般的に言えば、各タイプのシェルには相互に排他的なスクリプト言語があるとします。そして#!-line を使ってスクリプトするインタプリタを正確に指定します。たとえば、POSIX構文と構文のみを使用して移植可能なスクリプトを作成する場合、#!/bin/shPOSIXシェルを拡張する配列やその他の項目を#!/bin/bash使用する場合を使用します。bash

テキストファイル#!/bin/shこれとは関係ありませんsudo

更新された質問では、-lineなしでスクリプトへの複数の呼び出しを表示します#!。インタプリタがsourceコマンド(source: not found)を理解していないか、ファイル(something: No such file or directory)を見つけることができないため、すべて失敗します。

要約すると、スクリプトのインタプリタを指定するには、常に -line を使用します#!

sourceまた: を使用するとき./something$PATH

関連:

答え2

更新:質問が大幅に修正されたので、私の答えでなければなりません。
「スクリプト」と見なされるものの標準定義がないことがわかりましたが、単にコマンドリストを含むファイルであっても、シェルによって実行される限り、「スクリプト」になります。したがって、スクリプトの上部にシェルが指定されていない場合は、デフォルトの動作(sh)が採用されることに注意してください。
前の回答:bashが現在のシステムにない場合、bashismを理解できないため、スクリプトは失敗するはずです
。実験してみよう!sh

~/Downloads/test$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4  8月 31  2016 /bin/sh -> dash

shまず、そうでないことを確認してくださいbash。を使用して別のbashスクリプトを呼び出し
bash.shます。bashsudo

:~/Downloads/test$ cat bash.sh 
#!/bin/bash

sudo ./sudo_bash.sh

dash.sh((i++))あなたの言葉に従ってbashismが失敗しなければならないことを示すダッシュスクリプト。

:~/Downloads/test$ cat dash.sh 
#!/bin/sh

i=0
((i++))
echo $i

確認しよう

:~/Downloads/test$ ./dash.sh 
./dash.sh: 4: ./dash.sh: i++: not found
0
:~/Downloads/test$ 

美しく失敗しました。これでsudo_bash.shb​​ashスクリプトです。 sudoコマンドを使用してbash.shで実行します。おっしゃったように実際に分岐した場合でもsh失敗しなければなりません。

:~/Downloads/test$ cat sudo_bash.sh 
#!/bin/bash

i=0
((i++))
echo $i

:~/Downloads/test$ ./bash.sh 
[sudo] password for cs-server: 
1
:~/Downloads/test$

実行成功。これは新しい環境が利用できないことを証明します/bin/sh

I'd like to know why sudo uses sh as default.  

歴史的に、最初のシェルはshだったので、互換性のために名前が保持されます。

Is it so that it can be configured to other shells?

もちろん、shのシンボリックリンクを変更するだけです。

:~/Downloads/test$ cat text_file 
i=0
((i++))
echo $i
:~/Downloads/test$ chmod +x text_file 
:~/Downloads/test$ sudo ln -sf bash /bin/sh
:~/Downloads/test$ sudo ./text_file
1
:~/Downloads/test$ sudo ln -sf dash /bin/sh
:~/Downloads/test$ sudo ./text_file
./text_file: 2: ./text_file: i++: not found
0

関連情報