web-dev-qa-db-ja.com

/ bin / shリンクを一時的に変更する

/bin/shをBashにする必要があるソフトウェアがありますが、UbuntuのデフォルトはDashであり、デフォルトのままにしておきます。永続的にBashに変更したくありません。

実行中のターミナルセッションでのみ変更する方法はありますか?したがって、このターミナルで実行されているプログラムには、bashにリンクされた/bin/shが表示されますが、システムの残りの部分にはまだDashが表示されますか?または、/bin/shをBashとして表示するようにソフトウェアをだますことができますか?

私はこのソフトウェアを書いておらず、/bin/bashの代わりに/bin/shを使用するようにハッキングすることは、実際にはオプションではありません。

8
corwin

すでに2つの回答がchrootingとマウントのバインドを示唆しています。3番目の密接に関連するオプションがあります:mount namespacesunshareプログラムを使用 を使用すると、新しいマウント名前空間を作成できます。この名前空間内のマウントは、他の名前空間に影響しません。

たとえば、1つの端末で次のことを行います。

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.

そして別の:

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

したがって、この柔軟性のないプログラムを独自のマウント名前空間で実行できます。

10
muru

スクリプトの場合は、次のようにスクリプトを呼び出します

bash scriptname.sh

リンクを変更する必要はまったくありません。

コンパイルされた実行可能ファイルの場合、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

次に、プログラムまたはSudo chroot rootfs /yourprogramを実行します


ただし、実際には、/bin/bash/bin/shへのシンボリックリンクとして使用できない理由はありません。実際、 バージョン6.10より前 Ubuntuは/bin/bash/bin/shとして使用していましたが、/bin/shがPOSIXのはるかに高速で無駄のない実装であったために切り替わりました/bin/sh(つまり、UnixライクなオペレーティングシステムユーティリティとOSが動作し、内部の一部を実装する方法がPOSIX標準に準拠している)、および移植性の理由による。 /bin/dashがどのように生まれたのかに関する歴史的なメモについても Gillesの回答を読む も強くお勧めします。互換性については、POSIX機能を使用してdash用に記述されたスクリプトは、bashがデフォルトのシェルである場合に実行されます。通常、問題を引き起こすのは他の方法です-bashには、 /bin/sh構文 や配列など、<<<で必要とされない機能があります。

さらに、問題のコマンドはおそらく/bin/bashへのシンボリックリンクとして/bin/shを使用するRHELまたはCentOSを念頭に置いて記述されているため、2つのことが示唆されます。原則。その場合、他のOSを念頭に置いて作成されている場合は、単に/bin/shを再リンクするよりも多くの問題が発生する可能性があるため、コマンドが必要とする他のものを確認することもお勧めします。

14

1つの可能性は、単一ファイルのバインドマウントです。これを行うには、mountファイル/bin/bash just over/bin/dash so bash種類のカバーまたは非表示dash 。手順は次のとおりです(逆も含む)。

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 --

ただし、シンボリックリンクを直接hideするためにmount --bind /bin/bash /bin/shしようとしませんでした。上記のmountトリックは、bashとdashを同一にするだけなので、shbashを指しますが、dashを参照します。また、これは現在のターミナルウィンドウだけでなく、システム全体のソリューションです。


私は告白しなければなりません、これはやり過ぎかもしれません、そして単に一時的にシンボリックリンクを変更することははるかに簡単です。別の可能な方法を示したかっただけです。

5
PerlDuck

エイリアスを使用して、現在のセッションだけで変更できるようにする必要があります。ターミナルでコマンドを実行する前に:

alias sh=bash

これは一時的なものであり、実行元の端末でのみアクティブになります。

ただし、スクリプトで絶対パスを使用している場合、これは機能しません。

そのようなものとしては良い考えですが、ソフトウェアが明示的なパス名で/ bin/shを直接呼び出した場合、動作しません。とにかく、そのソフトウェアはそのような仮定をして非常に適切に設計されていないようです。使用する必要がある場合は、適切な環境を準備およびリセットするスクリプトから実行する可能性があります。 –バナジウム

残念ながら、スクリプトを「ハッキング」することが唯一の選択肢かもしれません。 @vanadiumとのコンボごとに、次のようなラッパースクリプトを作成できます。

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

ただし、スクリプトの実行中は、システム上で明示的にダッシュを必要としないものを望みます。

1