如何在 Windows 10 上将 PowerShell 7 定向到 运行 WSL2 中的 bash (Ubuntu) 脚本?

How can I direct PowerShell 7 to run a bash (Ubuntu) script in WSL2 on Windows 10?

我想将调用 bash/wsl 并在 bash 中的工作目录上运行以下代码的 PowerShell 脚本放在一起:

for f in $(find -type l);do cp --remove-destination $(readlink $f) $f;done;

我似乎只能让 wsl 更改目录:

param (
    [Parameter(Mandatory=$true,Position=0)]
    [String]$Folder
)

wsl.exe --cd $Folder

我试过:

wsl -c 'for f in $(find -type l);do cp --remove-destination $(readlink $f) $f;done;'

wsl.exe 'for f in $(find -type l);do cp --remove-destination $(readlink $f) $f;done;'

此外,出于某种原因,我在第一次调用 wsl.exe 后无法使用任何其他命令。例如,以下内容不起作用:

param (
    [Parameter(Mandatory=$true,Position=0)]
    [String]$Folder
)

wsl.exe --cd $Folder
wsl.exe echo "Hello World" # Never executes

我对 linux 和 Ubuntu 没有任何经验,所以我觉得我错过了一些非常简单的东西 - 因此 post.

如何从 Windows Powershell 7 执行 bash/wsl2 命令?

非常感谢任何帮助。

I have a feeling I'm missing something incredibly simple

不是真的。根据我的经验,从一种脚本语言调用另一种脚本语言很少 what-I-would-call “简单” ;-)。

这是从帮助中找出答案的一个很好的尝试,但不幸的是,wsl --help 输出中没有足够的细节来从中找出答案。

不过,如帮助中所述,在使用 wsl.exe 命令的 WSL 实例中,有一些结构可用于 运行ning 命令。

  • wsl <commandline>:运行命令行作为默认参数 shell。
  • wsl -e <command>:运行命令代替 shell

请注意,为了安全起见,我将用更温和的版本替换您的 command-lines ;-)。

for f in $(find -xdev -type l); do echo $f "----" $(readlink $f); done

旁注:当我将 findfor 一起使用时有人曾向我指出 - Why is looping over find's output bad practice?,所以它会find -xdev -type l | xargs -I % sh -c "echo -n % '---- '; readlink %" 确实更好,但我们将把它留在 for 循环中以演示此处的部分问题。

以下两次尝试失败,因为...

  • wsl --cd ~ -c 'for f in $(find -xdev -type l); do readlink $f; done'

    -c 不是 wsl.exe

    可以理解的标志
  • wsl.exe --cd ~ 'for f in $(find -xdev -type l); do readlink $f; done'

    这相当于 运行ning cd ~; for f in $(find -xdev -type l); do readlink $f; done,当然也行不通。

    实际上,回想起来,这可能对您有用。它对我来说失败了,因为我的默认 shell 是 Fish,但是 wsl 似乎确实试图 运行 默认 shell 和 -c 对于任何 command-line 传入。

    可能对你来说失败了,因为你在调用它之前没有在同一个 command-line 上设置目录(通过 --cd)。

  • wsl.exe --cd ~ -e 'for f in $(find -xdev -type l); do readlink $f; done'

    而且,虽然你没有提到尝试这个,但这个特定的也不会起作用,因为 -e 需要是一个单一的“命令”,但这是一个完整的命令行 shell 内置函数,例如 for.

“Aaargggh!”,你一直在说,对吧?赶上22?需要-c才能到达shell,但是wsl指令无法通过

所以,我们使用:

wsl --cd ~ -e sh -c 'for f in $(find -xdev -type l); do echo $f "----" $(readlink $f); done'

那个:

  • 更改主目录(当然,您可以用 PowerShell 中的 $FOLDER 变量替换)
  • 执行sh shell(如果你需要它的任何构造,你也可以使用Bash(或任何其他shell或命令)
  • 通过 -c 将命令行传递给 shell。对于大多数 shell、POSIX 或其他人来说,这是一个相当正常的论点。

注意(根据经验)PowerShell 和 WSL/sh 之间的引用规则可能会变得相当“不守规矩”。我发现随着示例变得越来越复杂,通常最好将 shell 命令放在脚本 inside WSL 中,然后您可以从 PowerShell 执行该脚本。例如,类似于:

wsl --cd ~ -e sh -c "~/.local/bin/myscript.sh"
--cd 注意

使用两个单独的 wsl 命令,如您的 --cd 示例:

wsl.exe --cd $Folder
wsl.exe echo "Hello World" # Never executes

假设您是通过脚本执行的,第一行:

  • 更改到指定目录
  • 运行默认 shell,这样您就处于交互式会话中

如果你然后退出 shell (Ctrl+Dexit), 然后你应该看到第二个命令的输出。

如果您从 PowerShell 运行 通过以下方式查看它,您也可以交互式地看到它:

wsl --cd ~ ; wsl echo Hello