Thay đổi / bin / sh liên kết tạm thời


9

Tôi có một phần mềm yêu cầu /bin/shphải là Bash, nhưng đối với Ubuntu, mặc định là Dash và tôi muốn giữ nó mặc định; Tôi không muốn đổi nó thành Bash vĩnh viễn.

Có cách nào để thay đổi nó chỉ cho một phiên cuối đang chạy không? Vì vậy, một chương trình đang chạy trong thiết bị đầu cuối này sẽ thấy /bin/shđược liên kết với bash nhưng phần còn lại của hệ thống vẫn sẽ thấy Dash? Hoặc tôi có thể lừa phần mềm để xem /bin/shlà Bash ngay cả khi nó không?

Tôi đã không viết phần mềm này và hack nó để sử dụng /bin/bashthay vì /bin/shkhông thực sự là một lựa chọn.


2
Bạn có thể thay đổi tạm thời - nhưng không (AFAIK) giới hạn phạm vi trong một phiên cuối. Xem ví dụ / bin / sh là một liên kết tượng trưng không trỏ đến / bin / bash
Steeldo


7
Dù bạn làm gì, xin vui lòng báo cáo đây là một lỗi cho phần mềm được đề cập. Bởi vì giả sử /bin/shbash một lỗi, và nó gây ra những vấn đề thực tế (như bạn đang tìm hiểu). Nếu không ai phàn nàn, nó có thể không bao giờ thay đổi.
marcelm

1
@SergiyKolodyazhnyy Nếu lỗi không gây ra sự cố trên (các) nền tảng duy nhất mà họ hỗ trợ, thì có lẽ họ có thể thoát khỏi nó. Nó vẫn là một lỗi mặc dù.
marcelm

1
Phần mềm là Petalinux được phát hành bởi một công ty "nhỏ" có tên Xilinx, và theo tài liệu Ubuntu 16.04 được hỗ trợ (cùng với CentOS và RHEL), vì vậy tôi sẽ nói đó là một lỗi.
corwin

Câu trả lời:


10

Hai câu trả lời đã đề xuất gắn kết và gắn kết gắn kết, và có một tùy chọn thứ ba, liên quan chặt chẽ: không gian tên gắn kết . Sử dụng unsharechương trình , bạn có thể tạo một không gian tên mount mới và các mount trong không gian tên này sẽ không ảnh hưởng đến các không gian tên khác.

Ví dụ: trong một thiết bị đầu cuối, tôi làm:

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.

Và trong một:

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

Vì vậy, bạn có thể chạy chương trình không linh hoạt này trong không gian tên mount riêng của nó.


14

Nếu đó là một kịch bản, chỉ cần gọi kịch bản là

bash scriptname.sh

Không cần phải thay đổi liên kết nào cả.

Để thực thi được biên dịch, bạn có thể đi tuyến đường 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

Và sau đó chạy chương trình của bạn hoặc sudo chroot rootfs /yourprogram


Tuy nhiên, trong thực tế không có lý do tại sao bạn không thể sử dụng /bin/bashlàm liên kết tượng trưng /bin/sh. Trong thực tế, trước khi phiên bản 6.10 Ubuntu đã được sử dụng /bin/bashnhư /bin/sh, và sau đó họ chuyển do /bin/shlà nhanh hơn nhiều, thực hiện gọn gàng hơn của POSIX /bin/sh(có nghĩa là, nó tuân theo chuẩn POSIX bao Unix-like hoạt động tiện ích hệ thống và hệ điều hành nên cư xử và thực hiện một số nội bộ của họ), và vì lý do tính di động. Tôi thực sự khuyên bạn nên đọc câu trả lời của Gilles cũng như các ghi chú lịch sử về cách thức /bin/dashdiễn ra. Về khả năng tương thích, các tập lệnh được viết để dashsử dụng các tính năng POSIX sẽ chạy với bashvỏ mặc định hoàn toàn tốt. Thông thường, đó là cách khác gây ra vấn đề -bashcó các tính năng không được yêu cầu bởi /bin/sh, như <<<cú pháp hoặc mảng.

Ngoài ra, lệnh được đề cập có lẽ được viết bằng RHEL hoặc CentOS, được sử dụng /bin/bashnhư một liên kết tượng trưng /bin/sh, gợi ý hai điều: có lẽ chúng nhắm mục tiêu HĐH cụ thể và không tuân thủ các nguyên tắc POSIX. Trong trường hợp đó, bạn cũng nên kiểm tra những thứ khác mà lệnh yêu cầu, vì nếu nó thực sự được viết với một hệ điều hành khác, bạn có thể gặp nhiều vấn đề hơn là chỉ liên kết lại /bin/sh.


2
CƯỜI LỚN. Cuộc sống có thể rất đơn giản :-)
PerlDuck

1
Bạn đã kiếm được upvote của tôi :)
Joshua Besneatte

@JoshuaBesneatte Cảm ơn bạn! Vui mừng bạn thấy câu trả lời của tôi hữu ích
Sergiy Kolodyazhnyy

3
+1 và có thể tốt hơn để tạo liên kết cứng thay vì bản sao (thông qua lnhoặc cp -l).
David Foerster

1
Cân nhắc mount --rbind --make-rslavehơn là cp -r. Có thể được thực hiện chỉ đọc là tốt. Cũng sudo chrootchạy script như root mà có thể không tối ưu.
Roman Odaisky

5

Một khả năng sẽ là một liên kết gắn kết của một tập tin duy nhất. Để làm điều này, bạn gắn kết các tập tin /bin/bashchỉ hơn /bin/dash để bashloại bìa hoặc da dash. Dưới đây là các bước (bao gồm cả đảo ngược):

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

Tôi đã không cố gắng để mount --bind /bin/bash /bin/shtrực tiếp ẩn symlink. Thủ mountthuật trên chỉ làm cho bash và dash giống hệt nhau để shnói đến bashmặc dù nó trỏ đến dash. Ngoài ra, đây là một giải pháp toàn hệ thống, không chỉ cho cửa sổ thiết bị đầu cuối hiện tại.


Tôi phải thú nhận, điều này có thể là quá mức cần thiết và chỉ cần thay đổi liên kết tượng trưng tạm thời dễ dàng hơn nhiều. Tôi chỉ muốn thể hiện một cách khác có thể.


1

Bạn sẽ có thể thay đổi nó cho phiên hiện tại bằng cách sử dụng bí danh. Trước khi chạy lệnh của bạn trong thiết bị đầu cuối:

alias sh=bash

Điều này sẽ là tạm thời và chỉ hoạt động trong thiết bị đầu cuối được thực hiện từ đó.

TUY NHIÊN: Điều này sẽ KHÔNG LÀM VIỆC nếu tập lệnh của bạn sử dụng các đường dẫn tuyệt đối.

Ý tưởng tốt là như vậy, nhưng nếu phần mềm gọi trực tiếp / bin / sh với tên đường dẫn rõ ràng, nó sẽ không hoạt động. Dù sao, phần mềm đó dường như không được thiết kế rất hợp lý khi đưa ra các giả định như vậy. Tôi có thể sẽ chạy nó từ một kịch bản chuẩn bị và thiết lập lại môi trường thích hợp nếu tôi phải sử dụng nó. - vanadi

Thật không may, "hack" tập lệnh có thể là lựa chọn duy nhất của bạn. Mỗi convo với @vanadi, bạn có thể tạo một tập lệnh bao bọc như thế này:

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

Tuy nhiên, trong suốt thời gian của tập lệnh của bạn, tốt hơn là bạn không hy vọng gì vào hệ thống của mình yêu cầu rõ ràng.


3
Ý tưởng tốt là như vậy, nhưng nếu phần mềm gọi trực tiếp / bin / sh với tên đường dẫn rõ ràng, nó sẽ không hoạt động. Dù sao, phần mềm đó dường như không được thiết kế rất hợp lý khi đưa ra các giả định như vậy. Tôi có thể sẽ chạy nó từ một kịch bản chuẩn bị và thiết lập lại môi trường thích hợp nếu tôi phải sử dụng nó.
vanadi

Tôi sẽ quan tâm để xem bạn sẽ chuẩn bị môi trường như thế nào. bạn sẽ sử dụng chroot?
Joshua Besneatte

Tôi không có những ý tưởng đầy tham vọng như vậy. Tôi chỉ nghĩ về một kịch bản sẽ tạm thời có liên kết sh để bash và thiết lập lại khi hoàn thành. Vấn đề chính trong câu hỏi này là "phần mềm" liên quan, tôi nghĩ vậy.
vanadi

Điều gì sẽ xảy ra nếu một cái gì đó khác cần dash trong khi liên kết tượng trưng đã được di chuyển .... một cái gì đó như ln -sf / bin / bash / bin / sh ở đầu ra và ln -sf / bin / dash / bin / sh khi hoàn thành?
Joshua Besneatte

Hầu hết các quy trình khác có thể sẽ vui vẻ sử dụng bash thay vì dấu gạch ngang nếu liên kết được thay đổi. Vâng, trong vô vọng đó, nhưng để bắt chước tình hình hiện tại, tôi sẽ tạo các liên kết tương đối, tức là "cd / bin; ln -sf bash sh", nhưng đó có lẽ là một chi tiết thuần túy không quan trọng trong thực tế.
vanadi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.