เปลี่ยน / bin / sh ลิงก์ชั่วคราว


9

ฉันมีซอฟต์แวร์บางส่วนที่ต้องใช้/bin/shBash แต่สำหรับ Ubuntu ค่าเริ่มต้นคือ Dash และฉันต้องการให้เป็นค่าเริ่มต้น ฉันไม่ต้องการเปลี่ยนเป็น Bash อย่างถาวร

มีวิธีการเปลี่ยนเฉพาะสำหรับเซสชันเทอร์มินัลที่กำลังทำงานอยู่หรือไม่ ดังนั้นโปรแกรมที่รันในเทอร์มินัลนี้จะเห็นการ/bin/shเชื่อมโยงกับ bash แต่ส่วนที่เหลือของระบบจะยังคงเห็น Dash หรือไม่ หรือฉันจะหลอกให้ซอฟต์แวร์ดู/bin/shเป็น Bash แม้ว่าจะไม่ใช่

ฉันไม่ได้เขียนซอฟต์แวร์นี้และการแฮ็กให้ใช้/bin/bashแทนที่จะ/bin/shเป็นตัวเลือกจริงๆ


2
คุณสามารถเปลี่ยนได้ชั่วคราว - แต่ไม่ จำกัด (AFAIK) เพื่อ จำกัด ขอบเขตของเซสชันเทอร์มินัลเดียว ดูตัวอย่าง/ bin / sh เป็นลิงก์สัญลักษณ์ที่ไม่ได้ชี้ไปที่ / bin / bash
steeldriver

2
อาจเป็นไปได้ที่น่าสนใจ: unix.stackexchange.com/questions/468289/…
ejjl

7
โปรดรายงานสิ่งนี้เป็นข้อบกพร่องสำหรับซอฟต์แวร์ที่เป็นปัญหา เพราะสมมติว่า/bin/shเป็นbash เป็นข้อผิดพลาดและมันก็ทำให้เกิดปัญหาที่เกิดขึ้นจริง (ตามที่คุณกำลังค้นหาออก) หากไม่มีใครบ่นก็อาจไม่เคยเปลี่ยน
marcelm

1
@SergiyKolodyazhnyy หากข้อผิดพลาดไม่ทำให้เกิดปัญหากับแพลตฟอร์มเดียวที่พวกเขาสนับสนุนพวกเขาก็อาจจะได้รับไปด้วย มันยังคงเป็นข้อบกพร่อง
marcelm

1
ซอฟต์แวร์นี้เป็น Petalinux ที่ออกโดย บริษัท "เล็ก" ชื่อ Xilinx และรองรับเอกสาร Ubuntu 16.04 (พร้อม CentOS และ RHEL) ดังนั้นฉันจะบอกว่ามันเป็นบั๊ก
รวิน

คำตอบ:


10

สองคำตอบอยู่แล้วแนะนำให้ chrooting และผูกม้าและมีสามตัวเลือกที่เกี่ยวข้องอย่างใกล้ชิดติด namespaces การใช้unshareโปรแกรมคุณสามารถสร้างเนมสเปซเมานต์ใหม่และการเมาท์ภายในเนมสเปซนี้จะไม่ส่งผลกระทบต่อเนมสเปซอื่น

ตัวอย่างเช่นในเทอร์มินัลหนึ่งฉันทำได้:

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

ดังนั้นคุณสามารถเรียกใช้โปรแกรมที่ไม่ยืดหยุ่นนี้ได้ในเนมสเปซของตัวเอง


14

หากเป็นสคริปต์ให้เรียกสคริปต์เป็น

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เป็น symlink /bin/shได้ ในความเป็นจริงก่อนหน้าเวอร์ชัน 6.10 Ubuntu ใช้/bin/bashเป็น/bin/shและจากนั้นพวกเขาก็เปลี่ยนเนื่องจาก/bin/shการติดตั้ง POSIX /bin/shที่รวดเร็วขึ้นและใช้งานได้น้อยลง(นั่นคือมันปฏิบัติตามมาตรฐาน POSIX สำหรับวิธีที่ยูทิลิตี้ระบบปฏิบัติการ Unix และ OS ควรปฏิบัติ ใช้งาน internals ของพวกเขา) และเนื่องจากเหตุผลในการพกพา ฉันขอแนะนำให้อ่านคำตอบของ Gillesและบันทึกทางประวัติศาสตร์/bin/dashเกี่ยวกับสาเหตุที่เกิดขึ้น สำหรับความเข้ากันได้สคริปต์ที่เขียนขึ้นเพื่อdashใช้คุณสมบัติ POSIX จะทำงานด้วยbashการเป็นเชลล์เริ่มต้นได้อย่างสมบูรณ์แบบ โดยปกติแล้ววิธีอื่น ๆ ที่ทำให้เกิดปัญหา -bashมีคุณสมบัติที่ไม่ต้องการ/bin/shเช่น<<<ไวยากรณ์หรืออาร์เรย์

นอกจากนี้คำสั่งที่เป็นปัญหาอาจถูกเขียนด้วย RHEL หรือ CentOS ในใจซึ่งใช้/bin/bashเป็นลิงก์เพื่อ/bin/shแนะนำสองสิ่ง: พวกเขาอาจกำหนดเป้าหมายระบบปฏิบัติการเฉพาะและไม่ปฏิบัติตามหลักการ POSIX ในกรณีเช่นนี้คุณควรตรวจสอบสิ่งอื่น ๆ ที่คำสั่งต้องการเนื่องจากถ้ามันเขียนด้วยระบบปฏิบัติการอื่นในใจคุณอาจพบปัญหามากกว่าการเชื่อมโยง/bin/shใหม่


2
ฮ่า ๆ. ชีวิตจะง่ายดังนั้น :-)
PerlDuck

1
คุณได้รับ upvote ของฉัน :)
โจชัว Besneatte

@JoshuaBesneatte ขอบคุณ! ดีใจที่คุณพบคำตอบของฉันมีประโยชน์
Sergiy Kolodyazhnyy

3
+1 และอาจเป็นการดีกว่าถ้าจะสร้างฮาร์ดลิงก์แทนการคัดลอก (ผ่านlnหรือcp -l)
David Foerster

1
พิจารณามากกว่าmount --rbind --make-rslave cp -rสามารถทำเป็นอ่านอย่างเดียวได้เช่นกัน นอกจากนี้ยังsudo chrootทำงานสคริปต์ที่เป็นรากซึ่งอาจจะไม่ดีที่สุด
Roman Odaisky

5

ความเป็นไปได้อย่างหนึ่งคือการผูกไฟล์เดียว การทำเช่นนี้คุณติดไฟล์/bin/bashเพียงกว่า /bin/dashเพื่อให้การจัดเรียงของผ้าห่มหรือหนัง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 --

ผมไม่ได้พยายามที่จะmount --bind /bin/bash /bin/shโดยตรงซ่อน symlink แม้ว่า ดังกล่าวข้างต้นmountเคล็ดลับเพียงแค่ทำให้ทุบตีและรีบเพื่อให้เหมือนกันว่าshหมายถึงแม้ว่ามันจะชี้ไปที่bash dashนอกจากนี้ยังเป็นโซลูชันทั่วทั้งระบบไม่เพียง แต่สำหรับหน้าต่างเทอร์มินัลปัจจุบัน


ฉันต้องสารภาพนี่อาจเกินความจริงและการเปลี่ยน symlink ชั่วคราวนั้นง่ายกว่ามาก ฉันแค่ต้องการแสดงอีกวิธีที่เป็นไปได้


1

คุณควรจะสามารถเปลี่ยนเป็นเพียงเซสชันปัจจุบันโดยใช้นามแฝง ก่อนรันคำสั่งของคุณในเทอร์มินัล:

alias sh=bash

สิ่งนี้จะเป็นการชั่วคราวและจะใช้งานในเทอร์มินัลที่ถูกเรียกใช้เท่านั้น

HOWEVER: สิ่งนี้จะไม่ทำงานหากสคริปต์ของคุณใช้เส้นทางที่แน่นอน

ความคิดที่ดีเช่นนี้ แต่ถ้าซอฟต์แวร์เรียกโดยตรง / bin / sh ด้วยชื่อพา ธ ที่ชัดเจนมันจะไม่ทำงาน อย่างไรก็ตามซอฟต์แวร์ดังกล่าวดูเหมือนจะไม่ได้รับการออกแบบอย่างเหมาะสมมากซึ่งทำให้สมมติฐานดังกล่าว ฉันอาจจะเรียกใช้จากสคริปต์ที่เตรียมและรีเซ็ตสภาพแวดล้อมที่เหมาะสมถ้าฉันต้องใช้เลย - วานาเดียม

น่าเสียดายที่ "แฮ็ค" สคริปต์อาจเป็นตัวเลือกเดียวของคุณ ในแต่ละครั้งที่มี @vanadium คุณสามารถสร้างสคริปต์ตัวห่อหุ้มดังนี้:

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

อย่างไรก็ตามในช่วงระยะเวลาของสคริปต์ของคุณคุณหวังว่าไม่มีสิ่งใดในระบบของคุณที่ต้องการเส้นประอย่างชัดเจน


3
ความคิดที่ดีเช่นนี้ แต่ถ้าซอฟต์แวร์เรียกโดยตรง / bin / sh ด้วยชื่อพา ธ ที่ชัดเจนมันจะไม่ทำงาน อย่างไรก็ตามซอฟต์แวร์ดังกล่าวดูเหมือนจะไม่ได้รับการออกแบบอย่างเหมาะสมมากซึ่งทำให้สมมติฐานดังกล่าว ฉันอาจจะเรียกใช้จากสคริปต์ที่เตรียมและรีเซ็ตสภาพแวดล้อมที่เหมาะสมหากฉันต้องใช้เลย
วานาเดียม

ฉันสนใจที่จะดูว่าคุณจะเตรียมสภาพแวดล้อมอย่างไร คุณจะใช้ chroot ไหม
Joshua Besneatte

ฉันไม่มีความคิดที่ทะเยอทะยานเช่นนี้ ฉันแค่คิดถึงสคริปต์ที่จะมีลิงค์ sh ชั่วคราวเพื่อทุบตีและรีเซ็ตเมื่อเสร็จแล้ว ปัญหาหลักของคำถามนี้คือผมคิดว่า
วานาเดียม

จะเกิดอะไรขึ้นหากมีสิ่งอื่นที่ต้องการขีดในขณะที่ลิงก์สัญลักษณ์ถูกย้าย .... สิ่งที่ต้องการ ln -sf / bin / bash / bin / sh ที่ begginning และ ln -sf / bin / dash / bin / sh เมื่อทำเสร็จแล้ว?
Joshua Besneatte

กระบวนการอื่น ๆ ส่วนใหญ่อาจจะใช้ bash แทนเส้นประอย่างมีความสุขหากลิงก์เปลี่ยนไป ใช่ในไร้สาระนั้น แต่เพื่อเลียนแบบสถานการณ์ปัจจุบันฉันจะสร้างการเชื่อมโยงที่เกี่ยวข้องเช่น "cd / bin; ln -sf bash sh" แต่นั่นอาจเป็นรายละเอียดที่ไม่เกี่ยวกับการปฏิบัติ
วานาเดียม
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.