Как запустить скрипт bash на wsl с помощью powershell?

В моем текущем каталоге в 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.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
91
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Чтобы запустить скрипт на 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 ./simple_script.sh вместо просто bash simple_script.sh. Это смущает.

Elad Maimoni 07.05.2022 16:50

В качестве предупреждения команда bash устарела в WSL. Вместо этого рекомендуется использовать команду wsl — она гораздо более гибкая.

NotTheDr01ds 08.05.2022 03:08

@EladMaimoni, bash ./simple_script.sh тоже работает и на самом деле предпочтительнее, потому что, в отличие от bash simple_script.sh, он не возвращается к поиску simple_script.sh скрипта в PATH, если его нет в текущем каталоге. Однако, как правило, вам не следует передавать сценарий оболочки со строкой шебанга в конкретную оболочку для прямого выполнения, если вы не уверены, что та же самая оболочка также указана в строке шебанга. Короче говоря: используйте вместо этого wsl -e ./simple_script.sh.

mklement0 11.05.2022 20:06

Надежный и эффективный способ выполнить сценарий оболочки на основе строки shebang из Windows — это через wsl.exe -e.

wsl -e ./simple_script.sh # !! ./ is required

Примечание:

  • Без ./, чтобы явно указать, что исполняемый файл находится в текущем каталоге, команда завершится ошибкой тихо (могут быть вызваны только исполняемые файлы, расположенные в каталогах, перечисленных в переменной среды PATHтолько по имени).

  • -eобходит задействует оболочку на стороне Linux и вместо этого позволяет системной функции Linux интерпретировать текстовый файл на основе строки shebang, который автоматически учитывает указанный интерпретатор.

    • Удивительно, но WSL считает, что файлы все, расположенные в файловой системе Окна, в том числе обычные текстовые, имеют набор исполняемый бит, что легко проверить с помощью 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 — требует ручной \-экранирование или встроенные " символы в аргументах, передаваемых внешним программам..

  • См. этот ответ для получения подробной информации, в том числе о потенциальном будущем исправлении, которое уже доступно как экспериментальная функция в версиях v7.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.

Другие вопросы по теме