Alterar / bin / sh link temporariamente

9

Eu tenho um software que precisa /bin/shser o Bash, mas para o Ubuntu o padrão é Dash e quero mantê-lo como padrão; Não quero alterá-lo para Bash permanentemente.

Existe uma maneira de alterá-lo apenas para uma sessão de terminal em execução? Portanto, um programa em execução neste terminal será /bin/shvinculado ao bash, mas o resto do sistema ainda verá o Dash? Ou posso enganar o software para ver /bin/shcomo Bash, mesmo que não seja?

Eu não escrevi este software e cortá-lo para usá-lo em /bin/bashvez de /bin/shnão é realmente uma opção.

corwin
fonte
2
Você pode alterá-lo temporariamente - mas não (AFAIK) limita o escopo a uma única sessão do terminal. Ver, por exemplo / bin / sh é um link simbólico que não aponta para / bin / bash
steeldriver
2
Possivelmente de interesse: unix.stackexchange.com/questions/468289/…
ejjl
7
Faça o que fizer, também relate isso como um bug para o software em questão. Porque assumindo /bin/shé bash é um bug, e que provoca problemas reais (como você está encontrando para fora). Se ninguém reclamar, isso nunca será alterado.
marcelm
1
@SergiyKolodyazhnyy Se o bug não causar problemas na (s) única (s) plataforma (s) suportada (s), é provável que eles possam se safar. Ainda é um bug.
marcelm
1
O software é o Petalinux lançado por uma empresa "pequena" chamada Xilinx, e de acordo com a documentação do Ubuntu 16.04 é suportado (junto com o CentOS e o RHEL), então eu diria que é um bug.
Corwin13 /

Respostas:

10

Duas respostas já sugerem montagens de chrooting e bind, e há uma terceira opção intimamente relacionada: montar namespaces . Usando o unshareprograma , você pode criar um novo espaço para nome de montagem e montagens nesse espaço para nome não afetarão outros espaços para nome.

Por exemplo, em um terminal, eu faço:

muru|[0] ~ sudo unshare -m /bin/bash
root@muru-1604:~# sudo mount --bind /bin/bash /bin/sh
root@muru-1604:~# /bin/sh --version
GNU bash, version 4.4.18(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
root@muru-1604:~# sudo -iu muru
muru|[0] ~ /bin/sh --version  # propagates
GNU bash, version 4.4.18(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

E em outro:

$ /bin/sh --version
/bin/sh: 0: Illegal option --

Portanto, você pode executar este programa inflexível em seu próprio espaço para nome de montagem.

muru
fonte
14

Se for um script, basta chamá-lo como

bash scriptname.sh

Não há necessidade de alterar os links.

Para executável compilado, você pode seguir a rota chroot:

mkdir rootfs
cp -a /usr rootfs/
cp -a /lib rootfs/
cp -a /lib64 rootfs/
cp /bin/bash  rootfs/bin/sh
cp yourprogram  rootfs/
sudo chroot rootfs  sh

E então execute seu programa ou sudo chroot rootfs /yourprogram


No entanto, na prática, não há razão para que você não possa usar /bin/bashcomo link simbólico para /bin/sh. De fato, antes da versão 6.10, o Ubuntu estava usando /bin/bashcomo /bin/she, em seguida, eles mudaram devido a /bin/shuma implementação muito mais rápida e mais enxuta do POSIX /bin/sh(ou seja, segue o padrão POSIX de como os utilitários de sistema operacional e o sistema operacional semelhantes ao Unix devem se comportar e implementar alguns de seus internos) e por motivos de portabilidade. Eu recomendo fortemente a leitura da resposta de Gilles , bem como notas históricas sobre como isso /bin/dashaconteceu. Quanto à compatibilidade, os scripts escritos para dashusar os recursos do POSIX serão executados bashcomo um shell padrão perfeitamente adequado. Geralmente, é o contrário que causa problemas -bashpossui recursos que não são necessários /bin/sh, como <<<sintaxe ou matrizes.

Além disso, o comando em questão provavelmente é escrito com o RHEL ou o CentOS em mente, que usa /bin/bashcomo um link simbólico para /bin/sh, sugere duas coisas: eles provavelmente foram direcionados ao SO específico e não aderiram aos princípios do POSIX. Nesse caso, também seria uma boa ideia verificar quais outras coisas o comando exige, pois se ele realmente foi escrito com outro sistema operacional em mente, você pode ter mais problemas do que apenas se reconectar /bin/sh.

Sergiy Kolodyazhnyy
fonte
2
RI MUITO. A vida pode ser tão simples :-)
PerlDuck
1
Você ganhou meu upvote :)
Joshua Besneatte
@JoshuaBesneatte Thank you! Que bom que você encontrar a minha resposta útil
Sergiy Kolodyazhnyy
3
+1 e pode ser melhor criar links físicos em vez de cópias (via lnou cp -l).
David Foerster
1
Considere em mount --rbind --make-rslavevez de cp -r. Também pode ser feito somente leitura. Também sudo chrootexecuta o script como root, o que pode não ser o ideal.
Roman Odaisky
5

Uma possibilidade seria uma montagem de ligação de um único arquivo. Para fazer isso, você monta o arquivo /bin/bashapenas sobre /bin/dash esse bashtipo de capa ou ocultação dash. Aqui estão as etapas (incluindo o inverso):

root@myhost:~# cd /bin

# situation before (bash and dash are different):
root@myhost:/bin# ls -l *sh*
-rwxr-xr-x 1 root root 1113504 Apr  4 20:30 bash
-rwxr-xr-x 1 root root  121432 Jan 25  2018 dash
lrwxrwxrwx 1 root root       4 Jul 13 11:38 sh -> dash
...

# mount /bin/bash over /bin/dash:
root@myhost:/bin# mount --bind /bin/bash /bin/dash

# situation now (bash and dash are the same):
root@myhost:/bin# ls -l *sh*
-rwxr-xr-x 1 root root 1113504 Apr  4 20:30 bash
-rwxr-xr-x 1 root root 1113504 Apr  4 20:30 dash
lrwxrwxrwx 1 root root       4 Jul 13 11:38 sh -> dash
...

# Now everything that runs `/bin/sh` in fact uses `/bin/bash`.

# check what the symlink "sh" says:
root@myhost:/bin# sh --version
GNU bash, version 4.4.19(1)-release (x86_64-pc-linux-gnu)
...

# undo the mount:
root@myhost:/bin# umount /bin/dash 

# situation now (bash and dash are different again):
root@myhost:/bin# ls -l *sh*
-rwxr-xr-x 1 root root 1113504 Apr  4 20:30 bash
-rwxr-xr-x 1 root root  121432 Jan 25  2018 dash
lrwxrwxrwx 1 root root       4 Jul 13 11:38 sh -> dash
...

# check what the symlink "sh" now says:
root@myhost:/bin# sh --version
sh: 0: Illegal option --

Eu não tentei ocultarmount --bind /bin/bash /bin/sh diretamente o link simbólico. O truque acima apenas torna o bash e o dash idênticos, de modo que se refere a embora aponte para . Além disso, esta é uma solução para todo o sistema, não apenas para a janela atual do terminal.mountshbashdash


Devo confessar que isso pode ser um exagero e simplesmente mudar o link simbólico temporariamente é muito mais fácil. Eu só queria mostrar outra maneira possível.

PerlDuck
fonte
1

Você deve poder alterá-lo apenas para a sessão atual usando um alias. Antes de executar seu comando no terminal:

alias sh=bash

Isso será temporário e somente ativo no terminal do qual foi executado.

NO ENTANTO: Isso NÃO FUNCIONARÁ se o seu script usar caminhos absolutos.

É uma boa ideia, mas se o software chamar diretamente / bin / sh com um nome de caminho explícito, ele não funcionará. De qualquer forma, esse software não parece ter sido projetado de maneira adequada para fazer tais suposições. Eu provavelmente o executaria a partir de um script que prepara e redefine o ambiente adequado, se eu tivesse que usá-lo. - vanádio

Infelizmente, "invadir" o script pode ser sua única opção. Por convenção com @vanadium, você pode criar um script de wrapper como este:

#!/bin/bash
sudo ln -sf /bin/bash /bin/sh
/run/my/script
sudo ln -sf /bin/dash /bin/sh

No entanto, durante a duração do seu script, é melhor esperar que nada no seu sistema exija explicitamente traço.

Joshua Besneatte
fonte
3
É uma boa idéia, mas se o software chamar diretamente / bin / sh com um nome de caminho explícito, ele não funcionará. De qualquer forma, esse software não parece ter sido projetado de maneira adequada para fazer tais suposições. Provavelmente, eu o executaria a partir de um script que prepara e redefine o ambiente adequado se eu tivesse que usá-lo.
vanadium
Eu ficaria interessado em ver como você prepararia o ambiente. você usaria chroot?
Joshua Besneatte
Eu não tinha idéias tão ambiciosas. Eu estava pensando em um script que teria temporariamente um link sh para bash e redefinir quando terminar. O principal problema nesta questão é com o "pedaço de software" em questão, eu acho.
vanadium
o que aconteceria se algo mais precisasse de traço enquanto o link simbólico fosse movido ... algo como ln -sf / bin / bash / bin / sh no início e ln -sf / bin / dash / bin / sh quando concluído?
Joshua Besneatte
A maioria dos outros processos provavelmente usará o bash em vez do dash se o link for alterado. Sim, em vão, mas para imitar a situação atual, eu faria links relativos, como "cd / bin; ln -sf bash sh", mas esse é provavelmente um detalhe purista que não importa na prática.
vanadium