Команда Perl qx() не работает должным образом

У меня есть perl-скрипт, как показано ниже, где я хочу получить доступ к сетевому пути на удаленной машине Windows с машины Linux, используя rsh.

$cmd = "rsh -l $username $host \"pushd \\\\network\\path\\to\\the\\directory && dir\"";
print $cmd, "\n";
print qx($cmd);

Когда я запускаю сценарий, третья строка выводит вывод The system cannot find the path specified. Однако, если я запускаю команду, напечатанную второй строкой, непосредственно из терминала, она работает нормально.

Я не могу понять, почему скрипт не работает. Если команда работает из терминала, она должна работать и с использованием qx().


person him    schedule 18.06.2019    source источник
comment
Непонятно, что именно запускать из командной строки. Если это именно та строка, которая у вас есть внутри $cmd = "rsh ....", вам может потребоваться добавить еще один уровень экранирования, поскольку двойные кавычки интерпретируют \\path как \path.   -  person Steffen Ullrich    schedule 18.06.2019
comment
Когда я запускаю команду, напечатанную второй строкой (то есть строковое значение $cmd), с терминала все работает нормально. Но третья строка (т.е. qx($cmd)) дает ошибку, как указано в вопросе. Я уже использовал четыре обратных слэша ` \\\\ ` в начале пути и выделил все остальные обратные слэши как ` \\ `.   -  person him    schedule 18.06.2019
comment
Лично я бы создал команду, используя комбинацию String::ShellQuote и Win32::ShellQuote.   -  person ikegami    schedule 19.06.2019


Ответы (1)


В то время как вы экранируете свои метасимволы от интерполяции двойными кавычками и удаленной оболочкой, qx может сама снова интерполировать строку, и в этом случае вам может потребоваться добавить еще один уровень экранирования. Из документации qx:

Строка, которая (возможно) интерполируется и затем выполняется как системная команда с /bin/sh или ее эквивалентом. ...
То, как оценивается эта строка, полностью зависит от интерпретатора команд в вашей системе. На большинстве платформ вам придется защитить метасимволы оболочки, если вы хотите, чтобы они воспринимались буквально. На практике это сложно сделать, так как неясно, как избежать каких символов. См. perlsec для чистого и безопасного примера ручной fork() и exec() для безопасной эмуляции обратных кавычек.

person Steffen Ullrich    schedule 18.06.2019