У цьому коді немає розбиття слів (як у функції, яка розбиває змінні на розкладені без котирування), оскільки $myvar
це не цитується.
Однак існує вразливість введення команд, $myvar
яка розширюється перед тим, як перейти до неї bash
. Тож його вміст трактується як баш-код!
Пробіли там спричинить передачу декількох аргументів cd
не через розбиття слів , а тому, що вони будуть синтаксично проаналізовані як декілька лексем у синтаксисі оболонки. Зі значенням bye;reboot
, що перезавантажиться! ¹
Тут вам потрібно:
sudo bash -c 'cd -P -- "$1"' bash "$myvar"
(Де ви передаєте вміст в $myvar
якості першого аргументу цього вбудованого скрипта, до відома , як і $myvar
і $1
були процитовані для їх відповідної оболонки , щоб запобігти МФС-софістику (і підстановку)).
Або:
sudo MYVAR="$myvar" bash -c 'cd -P -- "$MYVAR"'
(де ви передаєте вміст $myvar
змінної середовища).
Звичайно, нічого корисного ви не досягнете, запустивши лише cd
цей вкладений сценарій (крім перевірки, чи root
можна cd
там). Імовірно, ви хочете, щоб цей сценарій cd
там, а потім зробити щось інше, як-от:
sudo bash -c 'cd -P -- "$1" && do-something' bash "$myvar"
Якщо намір полягав у тому, sudo
щоб мати можливість cd
потрапляти в каталог, до якого ви інакше не маєте доступу, то це насправді не може працювати.
sudo sh -c 'cd -P -- "$1" && exec bash' sh "$myvar"
запустить інтерактив bash
зі своїм поточним каталогом у $myvar
. Але ця оболонка буде працювати як root
.
Ви можете зробити:
sudo sh -c 'cd -P -- "$1" && exec sudo -u "$SUDO_USER" bash' sh "$myvar"
Щоб отримати непривілейований інтерактив bash
із поточним каталогом $myvar
, але якщо у вас не було дозволів cd
входити до цього каталогу в першу чергу, ви не зможете робити нічого в цьому каталозі, навіть якщо це ваш поточний робочий каталог.
$ 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
Виняток буде, якщо у вас є дозвіл на пошук до самого каталогу, але не до одного з компонентів каталогу його шляху:
$ 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
¹ строго кажучи, для значень на $myvar
кшталт $(seq 10)
(буквально) було б розбиття слів звичайно після розширення заміни цієї команди bash
оболонкою, що починається якroot
cd
Має тільки ефект всерединіbash -c
оболонки.