Không có phân chia từ (như trong tính năng phân tách các biến khi mở rộng không được trích dẫn) trong mã đó như $myvar
không được trích dẫn.
Tuy nhiên, có một lỗ hổng tiêm lệnh như $myvar
được mở rộng trước khi được chuyển đến bash
. Vì vậy, nội dung của nó được hiểu là mã bash!
Các không gian trong đó sẽ khiến một số đối số được truyền vào cd
, không phải vì phân tách từ mà vì chúng sẽ được phân tích cú pháp dưới dạng một số mã thông báo trong cú pháp shell. Với giá trị bye;reboot
, nó sẽ khởi động lại!
Ở đây, bạn muốn:
sudo bash -c 'cd -P -- "$1"' bash "$myvar"
(trong đó bạn chuyển nội dung $myvar
là đối số đầu tiên của tập lệnh nội tuyến đó; lưu ý cách cả hai $myvar
và $1
được trích dẫn cho trình bao tương ứng của chúng để ngăn chặn phân tách từ IFS (và toàn cầu hóa)).
Hoặc là:
sudo MYVAR="$myvar" bash -c 'cd -P -- "$MYVAR"'
(nơi bạn chuyển nội dung $myvar
trong một biến môi trường).
Tất nhiên, bạn sẽ không đạt được bất cứ điều gì hữu ích bằng cách chỉ chạy cd
trong tập lệnh nội tuyến đó (ngoài việc kiểm tra xem root
có thể cd
vào đó không). Có lẽ, bạn muốn kịch bản cd
đó ở đó và sau đó làm một cái gì đó khác như:
sudo bash -c 'cd -P -- "$1" && do-something' bash "$myvar"
Nếu mục đích là sử dụng sudo
để có thể cd
vào một thư mục mà bạn không có quyền truy cập, thì điều đó không thể thực sự hoạt động.
sudo sh -c 'cd -P -- "$1" && exec bash' sh "$myvar"
sẽ bắt đầu tương tác bash
với thư mục hiện tại của nó trong $myvar
. Nhưng cái vỏ đó sẽ chạy như root
.
Bạn có thể làm:
sudo sh -c 'cd -P -- "$1" && exec sudo -u "$SUDO_USER" bash' sh "$myvar"
Để có được sự tương tác không có đặc quyền bash
với thư mục hiện tại $myvar
, nhưng nếu bạn không có quyền cd
vào thư mục đó ngay từ đầu, bạn sẽ không thể làm bất cứ điều gì trong thư mục đó ngay cả khi đó là thư mục làm việc hiện tại của bạn.
$ myvar=/var/spool/cron/crontabs
$ sudo sh -c 'cd -P -- "$1" && exec sudo -u "$SUDO_USER" bash' sh "$myvar"
bash-4.4$ ls
ls: cannot open directory '.': Permission denied
Một ngoại lệ sẽ là nếu bạn có quyền tìm kiếm đối với chính thư mục đó nhưng không phải là một trong các thành phần thư mục của đường dẫn của nó:
$ myvar=1/2
$ mkdir -p "$myvar"
$ chmod 0 1
$ cd 1/2
cd: permission denied: 1/2
$ sudo sh -c 'cd -P -- "$1" && exec sudo -u "$SUDO_USER" bash' sh "$myvar"
bash-4.4$ pwd
/home/stephane/1/2
bash-4.4$ mkdir 3
bash-4.4$ ls
3
bash-4.4$ cd "$PWD"
bash: cd: /home/stephane/1/2: Permission denied
Nói đúng ra, đối với các giá trị $myvar
like $(seq 10)
(theo nghĩa đen), tất nhiên sẽ có sự phân tách từ khi mở rộng thay thế lệnh đó bằng bash
shell bắt đầu nhưroot
cd
chỉ có tác dụng bên trongbash -c
vỏ.