como deixar sudo garfo bater em vez de sh?

2

de acordo com o sudo (8) :

Process model When sudo runs a command, it calls fork(2), sets up the execution environment as described above, and calls the execve system call in the child process.

Também descobri que o processo filho bifurcado executa seu comando usando sh .

Portanto, se o comando for um script bash com algum comando específico do bash, como source , o sh não o executará corretamente. Por exemplo:

% cat /tmp/wibble
source something
% ls -l /tmp/wibble
-rwxr-xr-x 1 user user 17 Aug 24 08:32 /tmp/wibble
% getent passwd root
root:x:0:0:root:/root:/bin/bash
% /tmp/wibble
/tmp/wibble: 1: /tmp/wibble: source: not found
% /bin/bash /tmp/wibble                                                                                                                                                                                                      ~ [pts/3.4028.1]
/tmp/wibble: line 1: something: No such file or directory
% /bin/dash /tmp/wibble
/tmp/wibble: 1: /tmp/wibble: source: not found
% /bin/sh /tmp/wibble
/tmp/wibble: 1: /tmp/wibble: source: not found
% echo $SHELL
/bin/zsh
% sudo /tmp/wibble
/tmp/wibble: 1: /tmp/wibble: source: not found
% sudo -s /tmp/wibble
/tmp/wibble: 1: /tmp/wibble: source: not found
% sudo -i /tmp/wibble
/tmp/wibble: line 1: something: No such file or directory
% export SHELL=/bin/bash
% sudo /tmp/wibble
/tmp/wibble: 1: /tmp/wibble: source: not found
% sudo -s /tmp/wibble
/tmp/wibble: line 1: something: No such file or directory
% sudo -i /tmp/wibble
/tmp/wibble: line 1: something: No such file or directory
%

Geralmente, podemos acrescentar uma opção -s a sudo para resolver esse problema, como no exemplo acima, mas gostaríamos de saber por que sudo usa sh como padrão. É para que possa ser configurado para outros shells?

    
por fatfatson 24.08.2017 / 07:19

2 respostas

3

Certifique-se de que o seu script comece com a #! -line apropriada.

Se um script for executável e começar com, por exemplo,

#!/bin/bash

(ou qualquer que seja o caminho para bash em seu sistema), então o script será interpretado por /bin/bash se você digitou sudo script , assim como um script Python seria interpretado por /usr/bin/python se sua primeira linha foi #!/usr/bin/python .

A questão se sh é bash ou algum outro shell é desinteressante aqui. Em geral, assume que cada tipo de shell é sua própria linguagem de script mutuamente exclusiva e usa a #! -line para especificar exatamente qual interpretador você escreveu o script. Se você, por exemplo, escrever um script portátil usando apenas a gramática e sintaxe POSIX, use #!/bin/sh , mas use #!/bin/bash se você usar as matrizes de bash ou outras coisas com as quais este shell estende o shell POSIX.

Quando um arquivo de texto não inicia com #! , /bin/sh é usado como fallback. Isso não tem nada a ver com sudo .

Na sua pergunta atualizada, você exibe várias invocações de um script sem #! -line. Todos eles falham porque o interpretador não entende o comando source ( source: not found ) ou porque não consegue encontrar o arquivo ( something: No such file or directory ).

Para resumir: Sempre especifique o interpretador para scripts usando uma #! -line.

Além disso: Ao usar source , especifique o caminho para o arquivo a ser usado, mesmo que seja apenas ./something , caso contrário, ele pode ser selecionado em algum lugar em $PATH .

Relacionados:

por 24.08.2017 / 08:22
0

UPDATE: a questão foi strongmente modificada, então tem que ser minha resposta.
Embora não tenha encontrado nenhum padrão que defina o que é considerado um "script", provavelmente, mesmo apenas um arquivo com lista de comandos é um "script", desde que ele esteja sendo executado pelo shell. Portanto, deve-se ter cuidado, pois, se nenhum shell for especificado na parte superior do script, o comportamento padrão (sh) será assumido.
RESPOSTA VELHA:
Se sh não for bash no sistema atual, o script falhará porque os bashisms não serão compreendidos.
Vamos fazer um experimento!

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

Antes de tudo, confirme que sh não é bash .
bash.sh vai utilizar bash . Ele chama outro script bash, usando sudo .

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

sudo ./sudo_bash.sh

dash.sh é um script de traço, para mostrar que ((i++)) bashism deve falhar de acordo com suas palavras.

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

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

Vamos confirmar

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

Belamente falhou. Agora, sudo_bash.sh é um script bash. Vamos executá-lo a partir do bash.sh com o comando sudo e, como você disse, se ele realmente for bifurcado com sh , ele também deverá falhar.

:~/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$

Executado com sucesso. Isso prova que o novo ambiente não usa /bin/sh .

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

Historicamente, o primeiro shell era sh, então o nome ainda é mantido por razões de compatibilidade.

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

Claro, basta alterar o link simbólico do seu 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
    
por 24.08.2017 / 08:20

Tags