AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / ubuntu / Perguntas / 980118
Accepted
James Newton
James Newton
Asked: 2017-11-26 05:40:22 +0800 CST2017-11-26 05:40:22 +0800 CST 2017-11-26 05:40:22 +0800 CST

script bash: resultados diferentes quando chamado com ou sem sudo

  • 772

No Ubuntu 16.04.3, tenho um script bash muito simples:

test.sh

[[ 0 == 0 ]] && result="true" || result="false"
echo $result
echo $USER $SHELL $0

Quando eu o chamo como usuário não raiz meou como root, ele funciona conforme o esperado. Se eu uso sudo ./test.sh, ele reclama de um erro de sintaxe:

$ ./test.sh
true
me /bin/bash ./test.sh

$ sudo su
# ./test.sh 
true
root /bin/bash ./test.sh

# exit
$ sudo ./test.sh
./test.sh: 1: ./test.sh: [[: not found
false
root /bin/bash ./test.sh

O que poderia estar causando isso? Como posso corrigi-lo para que mepossa usar este script normalmente e com sudo?

bash
  • 2 2 respostas
  • 2098 Views

2 respostas

  • Voted
  1. Best Answer
    dessert
    2017-11-26T05:50:05+08:002017-11-26T05:50:05+08:00

    Todo script começa com um Shebang , sem ele o shell que inicia seu script não sabe qual interpretador deve executar seu script 1 e pode - como no caso sudo ./script.shdaqui - executá-lo com sh, que no Ubuntu 16.04 está vinculado a dash. A expressão condicional [[ é um bashcomando composto , então dashnão sabe como lidar com isso e gera o erro que você encontrou.

    A solução aqui é adicionar

    #!/bin/bash
    

    como a primeira linha do seu script. Você pode obter o mesmo resultado ao chamá-lo explicitamente com sudo bash ./script.sh, mas um shebang é o caminho a percorrer.
    Para verificar qual shell executa seu script, adicione echo $0a ele. Isso não é o mesmo que echo $SHELL , citando wiki.archlinux.org :

    SHELL contém o caminho para o shell preferido do usuário. Observe que esse não é necessariamente o shell que está em execução no momento, embora o Bash defina essa variável na inicialização.

    1: Como você começou ./test.shcom bashapenas assumiu bash, o mesmo vale para o sudo susubshell.

    • 20
  2. terdon
    2017-11-26T09:07:02+08:002017-11-26T09:07:02+08:00

    Como @dessert explicou , o problema aqui é que seu script não tem uma linha shebang . Sem um shebang, sudoo padrão será tentar executar o arquivo usando /bin/sh. Não consegui encontrar documentado em lugar nenhum, mas confirmei verificando o sudocódigo fonte onde encontrei o seguinte no arquivo pathnames.h:

    #ifndef _PATH_BSHELL
    #define _PATH_BSHELL "/bin/sh"
    #endif /* _PATH_BSHELL */
    

    Isso significa "definir se a variável _PATH_BSHELLnão estiver definida, defina-a como /bin/sh". Então, no configurescript incluído no tarball fonte, temos:

    for p in "/bin/bash" "/usr/bin/sh" "/sbin/sh" "/usr/sbin/sh" "/bin/ksh" "/usr/bin/ksh" "/bin/bash" "/usr/bin/bash"; do
        if test -f "$p"; then
        found=yes
        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $p" >&5
    $as_echo "$p" >&6; }
        cat >>confdefs.h <<EOF
    #define _PATH_BSHELL "$p"
    EOF
    
        break
        fi
    done
    

    Este loop procurará /bin/bash, /usr/bin/sh, ou /sbin/she então definirá o que for encontrado primeiro . Como era o primeiro da lista e existe, é definido como . O resultado de tudo isso é que o shell padrão de , a menos que definido de outra forma, seja ./usr/sbin/sh/bin/ksh_PATH_BSHELL/bin/sh_PATH_BSHELL/bin/shsudo/bin/sh

    Portanto, sudoo padrão será executar as coisas usando /bin/she, no Ubuntu, um link simbólico para dash, um shell mínimo compatível com POSIX:

    $ ls -l /bin/sh
    lrwxrwxrwx 1 root root 4 Feb 27  2015 /bin/sh -> dash
    

    A [[construção é um recurso bash, não é definida pelo padrão POSIX e não é compreendida por dash:

    $ bash -c '[[ true ]] && echo yes'
    yes
    $ dash -c '[[ true ]] && echo yes'
    dash: 1: [[: not found
    

    Em detalhes, nas três invocações que você tentou:

    1. ./test.sh

      Não sudo; na ausência de uma linha shebang, seu shell tentará executar o próprio arquivo. Como você está executando o bash, isso será executado bash ./test.she funcionará efetivamente.

    2. sudo suseguido por ./test.sh.

      Aqui, você está iniciando um novo shell para o usuário root. Este será o shell definido na $SHELLvariável de ambiente para esse usuário e, no Ubuntu, o shell padrão do root é bash:

      $ grep root /etc/passwd
      root:x:0:0:root:/root:/bin/bash
      
    3. sudo ./test.sh

      Aqui, você está deixando sudoexecutar o comando diretamente. Como seu shell padrão é /bin/shexplicado acima, isso faz com que ele execute o script com /bin/sh, que é dashe falha, pois dashnão entende [[.


    Nota : os detalhes de como sudodefine o shell padrão parecem ser um pouco mais complexos. Tentei alterar os arquivos mencionados em minha resposta para apontar, /bin/bashmas sudoainda estava com o padrão /bin/sh. Portanto, deve haver alguns outros locais no código-fonte onde o shell padrão é definido. No entanto, o ponto principal (que sudoé padronizado para sh) ainda permanece.

    • 5

relate perguntas

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Existe um comando para listar todos os usuários? Também para adicionar, excluir, modificar usuários, no terminal?

    • 9 respostas
  • Marko Smith

    Como excluir um diretório não vazio no Terminal?

    • 4 respostas
  • Marko Smith

    Como descompactar um arquivo zip do Terminal?

    • 9 respostas
  • Marko Smith

    Como instalo um arquivo .deb por meio da linha de comando?

    • 11 respostas
  • Marko Smith

    Como instalo um arquivo .tar.gz (ou .tar.bz2)?

    • 14 respostas
  • Marko Smith

    Como listar todos os pacotes instalados

    • 24 respostas
  • Martin Hope
    Flimm Como posso usar o docker sem sudo? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    led-Zepp Como faço para salvar a saída do terminal em um arquivo? 2014-02-15 11:49:07 +0800 CST
  • Martin Hope
    ubuntu-nerd Como descompactar um arquivo zip do Terminal? 2011-12-11 20:37:54 +0800 CST
  • Martin Hope
    TheXed Como instalo um arquivo .deb por meio da linha de comando? 2011-05-07 09:40:28 +0800 CST
  • Martin Hope
    Ivan Como listar todos os pacotes instalados 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    David Barry Como determino o tamanho total de um diretório (pasta) na linha de comando? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher "Os seguintes pacotes foram retidos:" Por que e como resolvo isso? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford Como os PPAs podem ser removidos? 2010-07-30 01:09:42 +0800 CST

Hot tag

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve