Обойти Powershell для запуска команды zsh - PullRequest
1 голос
/ 16 января 2020

В Powershell (pw sh) Можно ли «обойти» Powershell, чтобы ничего не делать, и позволить основной оболочке выполнить эту работу?

Иногда мне нужно вызвать команду, которую я копирую из сайт или другой объект, который включает «\», а не «´» для разрыва строки - или другие параметры, которые Powershell пытается интерполировать.

Например:

 <Powershell Function> kubectl get rolebindings,clusterrolebindings \                                      
  --all-namespaces  \
  -o custom-columns='KIND:kind,NAMESPACE:metadata.namespace,NAME:metadata.name,SERVICE_ACCOUNTS:subjects[?(@.kind=="ServiceAccount")].name' | grep name

Ответы [ 2 ]

2 голосов
/ 17 января 2020

и пусть соответствующая оболочка выполнит всю работу?

PowerShell - это оболочка, так что базовой оболочки как таковой нет (в том смысле, что PowerShell не требуется не запускается из другой оболочки). Однако есть платформа-специфицированная c по умолчанию оболочки : cmd.exe на Windows и /bin/sh на Unix -подобных платформах.

Мне нужно вызвать команду, которую я копирую с сайта или другого сайта

До того, как PowerShell стал кроссплатформенным, --%, символ остановки парсинга был представлен в Windows PowerShell v3 именно для того, чтобы соответствовать вашему сценарию.

Учитывая, что Windows была единственной поддерживаемой платформой в то время, поведение сосредоточено на cmd.exe - и даже там оно не поддерживает продолжение строки cmd.exe через ^ символы конца строки.

В более общем смысле, пока оно пытается эмулирует поведение cmd.exe (например, путем расширения % -замкнутых токенов, таких как %USERNAME% как ссылки на переменные среды) без фактического делегирования последним, это не ' полностью .

В PowerShell Core (v6 +) --% поддерживается даже на Unix -подобной платформе Среднеквадратичное значение, но там мало пользы , учитывая, что семантика cmd.exe применяется даже там; в частности, '...' -цитирование поддерживается , а не .

(Обратите внимание, что PowerShell эмулирует одну /bin/sh функцию на Unix -подобных платформах, но только без использования
--%: globbing , т. е. расширение маркеров без кавычек, таких как *.txt, в соответствующие пути к файлам).


Однако, вы можете вызвать платформенную оболочку явно , например, передав скопированную командную строку в sh -c на Unix -подобных платформах, , используя (дословно) here-string для командной строки:

# Call the platform-native shell with a command crafted for it:
sh -c @'
  echo This line\
    keeps going\
    with --all-namespaces and\
    with -o custom-columns='KIND:kind,NAMESPACE'
'@

К сожалению, есть загвоздка :

Начиная с v7.0, PowerShell обрабатывает встроенные символы ". в аргументах, передаваемых внешним программам (таким как sh), принципиально не работает , требуя, чтобы встроенный " был вручную \ -эскапирован:

# !! BROKEN
sh -c @'
  echo "high noon"
'@

Чтобы это работало, вы должны \ -escape вручную :

# WORKAROUND
sh -c (@'
  echo "high noon"
'@ -replace '"', '\"')

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

1 голос
/ 17 января 2020

Не то, чтобы я знал. Я также не знаю ни одной оболочки, где это возможно, кроме как для Ruby, где у вас есть строковые литеральные операторы, которые значительно облегчают экранирование.

Я бы предложил, чтобы перед отправкой строк внешним командам, что вы преобразуете escape-последовательности PowerShell в целевые escape-последовательности времени выполнения. Это не проблема, уникальная для PowerShell, но с ней легче работать в других оболочках, потому что между другими средами выполнения больше совпадений специальных символов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...