В моем текущем каталоге в Windows у меня есть следующий файл сценария simple_script.sh:
#!/bin/bash
echo "hi from simple script"
Я хочу запустить этот скрипт на wsl через командную строку powershell.
Используя команду wsl, я не смог найти способ заставить wsl вызывать код скрипта.
Следующая команда работает (я думаю)
wsl bash -c "echo hi from simple script"
Однако при попытке загрузить содержимое скрипта в переменную и запустить его не удается, как ожидалось:
$simple_script = Get-Content ./simple_script.sh
wsl bash -c $simple_script
Не удается с:
bash: -c: option requires an argument
Я попробовал несколько вариантов. использование Get-Content с флагом -Raw, кажется, заставляет печатать первое слово в строке (но не всю строку). команды, которые не содержат символы '"', иногда работают. Но я не нашел последовательного способа.
Аналогично выглядящий вопрос, похоже, не работает напрямую с wsl и не запускает файл сценария, который находится в файловой системе Windows.





Чтобы запустить скрипт на wsl, вы просто вызываете bash
> bash simple_script.sh
hi from simple script
Чтобы сохранить его в переменной и запустить как bash скрипт внутри wsl или powershell, нет необходимости в Get-Content
> $simple_script = bash /mnt/c/Users/user-name/path/to/simple_script.sh
> Write-Output $simple_script
hi from simple script
ПРИМЕЧАНИЕ: Powershell имеет сопоставление псевдонима echo с Write-Output, поэтому вы также можете использовать echo
> $simple_script = bash /mnt/c/Users/user-name/path/to/simple_script.sh
> echo $simple_script
hi from simple script
Вы также можете получить контент, если это было вашей первоначальной целью.
> Get-Content simple_script.sh
#!/bin/bash
echo "hi from simple script"
> $content = Get-Content .\simple_script.sh
> Write-Output $content
#!/bin/bash
echo "hi from simple script"
В качестве предупреждения команда bash устарела в WSL. Вместо этого рекомендуется использовать команду wsl — она гораздо более гибкая.
@EladMaimoni, bash ./simple_script.sh тоже работает и на самом деле предпочтительнее, потому что, в отличие от bash simple_script.sh, он не возвращается к поиску simple_script.sh скрипта в PATH, если его нет в текущем каталоге. Однако, как правило, вам не следует передавать сценарий оболочки со строкой шебанга в конкретную оболочку для прямого выполнения, если вы не уверены, что та же самая оболочка также указана в строке шебанга. Короче говоря: используйте вместо этого wsl -e ./simple_script.sh.
Надежный и эффективный способ выполнить сценарий оболочки на основе строки shebang из Windows — это через wsl.exe -e.
wsl -e ./simple_script.sh # !! ./ is required
Примечание:
Без ./, чтобы явно указать, что исполняемый файл находится в текущем каталоге, команда завершится ошибкой тихо (могут быть вызваны только исполняемые файлы, расположенные в каталогах, перечисленных в переменной среды PATHтолько по имени).
-eобходит задействует оболочку на стороне Linux и вместо этого позволяет системной функции Linux интерпретировать текстовый файл на основе строки shebang, который автоматически учитывает указанный интерпретатор.
wsl -e ls -l ./simple_script.shЧто касается что ты пробовал:
$simple_script = Get-Content ./simple_script.sh
wsl bash -c $simple_script
Основная проблема заключается в том, что Get-Content по умолчанию возвращает множество строк, и попытка использовать этот массив в качестве аргумента для внешняя программа, такого как wsl, приводит к передаче элементов массива как отдельные аргументы.
немедленное решение - использовать переключатель -Raw, который заставляет Get-Content возвращать содержимое файла как одна, многострочная строка.
Однако из-за очень досадной давней ошибки PowerShell — по крайней мере, до версии 7.2.3 — требует ручной \-экранирование или встроенные " символы в аргументах, передаваемых внешним программам..
Поэтому:
# Using -Raw, read the file in full, as a single, multi-line string.
$simple_script = Get-Content -Raw ./simple_script.sh
# !! The \-escaping is needed up to at least PowerShell 7.2.3
wsl bash -c ($simple_script -replace '"', '\"')
Обратите внимание, что хотя это заманчиво обойти необходимость выхода, предоставив текст скрипта по трубопроводу (stdin), этот работает ли нет должным образом, начиная с PowerShell 7.2.3:
# !! Tempting, but does NOT work.
Get-Content -Raw ./simple_script.sh | wsl -e bash
Причина, по которой это не работает, заключается в том, что PowerShell неизменно добавляет новую строку Windows-формат (CRLF) к тому, что отправляется внешним программам через конвейер. не распознается Bash.
Это проблемное поведение обсуждается в Ошибка GitHub № 13579.
Моя ошибка заключалась в том, что я пытался
bash ./simple_script.shвместо простоbash simple_script.sh. Это смущает.