是否有可能编写一个在bash / shell和PowerShell中运行的脚本?

我需要创build一个集成脚本来设置一些环境variables,使用wget下载文件并运行它。

面临的挑战是它需要能够在Windows PowerShell和bash / shell上运行的SAME脚本。

这是shell脚本:

#!/bin/bash # download a script wget http://www.example.org/my.script -O my.script # set a couple of environment variables export script_source=http://www.example.org export some_value=floob # now execute the downloaded script bash ./my.script 

这在PowerShell中是一样的:

 wget http://www.example.org/my.script -O my.script.ps1 $env:script_source="http://www.example.org" $env:some_value="floob" PowerShell -File ./my.script.ps1 

所以我想知道这两个脚本是否可以在任一平台上合并并运行成功?

我一直在试图find一种方法,把他们在同一个脚本,并得到bash和PowerShell.exe忽略错误,但没有成功这样做。

任何猜测?

有可能的; 我不知道这是如何兼容的,但PowerShell将字符串视为文本,并最终显示在屏幕上,Bash将它们视为命令并尝试运行它们,并且都支持相同的函数定义语法。 所以,把一个函数名放在引号中,只有Bash会运行它,把“exit”放在引号中,只有Bash会退出。 然后编写PowerShell代码。

NB。 这是有效的,因为两个shell中的语法是重叠的,而且你的脚本很简单 – 运行命令并处理变量。 如果您尝试使用任何一种语言的更高级脚本(如果/然后,切换,大小写等),另一个可能会抱怨。

将此保存为dual.ps1 ,PowerShell对此感到满意, chmod +x dual.ps1 ,Bash将运行它

 #!/bin/bash function DoBashThings { wget http://www.example.org/my.script -O my.script # set a couple of environment variables export script_source=http://www.example.org export some_value=floob # now execute the downloaded script bash ./my.script } "DoBashThings" # This runs the bash script, in PS it's just a string "exit" # This quits the bash version, in PS it's just a string # PowerShell code here # -------------------- Invoke-WebRequest "http://www.example.org/my.script.ps1" -OutFile my.script.ps1 $env:script_source="http://www.example.org" $env:some_value="floob" PowerShell -File ./my.script.ps1 

然后

 ./dual.ps1 

在任一系统上。


编辑:你可以包含更复杂的代码,通过用不同的前缀评论代码块,然后让每种语言筛选出自己的代码并eval它(通常安全警告与eval一起使用),例如用这种方法(包含来自Harry Johnston的建议) :

 #!/bin/bash #posh $num = 200 #posh if (150 -lt $num) { #posh write-host "PowerShell here" #posh } #bash thing="xyz" #bash if [ "$thing" = "xyz" ] #bash then #bash echo "Bash here" #bash fi function RunBashStuff { eval "$(grep '^#bash' $0 | sed -e 's/^#bash //')" } "RunBashStuff" "exit" ((Get-Content $MyInvocation.MyCommand.Source) -match '^#posh' -replace '^#posh ') -join "`n" | Invoke-Expression