且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-12-05 13:38:46

这是可能的;我不知道它的兼容性如何,但是PowerShell将字符串视为文本,然后将它们显示在屏幕上,Bash将它们视为命令并尝试运行它们,并且两者都支持相同的函数定义语法.因此,将函数名称放在引号中,只有Bash将运行它,将退出"放入引号中,只有Bash将退出.然后再编写PowerShell代码.

It is possible; I don't know how compatible this is, but PowerShell treats strings as text and they end up on screen, Bash treats them as commands and tries to run them, and both support the same function definition syntax. So, put a function name in quotes and only Bash will run it, put "exit" in quotes and only Bash will exit. Then write PowerShell code after.

NB.之所以可行,是因为两个Shell中的语法重叠,并且您的脚本很简单-运行命令并处理变量.如果您尝试对其中一种语言使用更高级的脚本(如果/然后,用于,切换,区分大小写等),则另一种可能会抱怨.

NB. this works because the syntax in both shells overlaps, and your script is simple - run commands and deal with variables. If you try to use more advanced script (if/then, for, switch, case, etc.) for either language, the other one will probably complain.

将其另存为dual.ps1,以便PowerShell对其满意; chmod +x dual.ps1,以便Bash可以运行它

Save this as dual.ps1 so PowerShell is happy with it, chmod +x dual.ps1 so Bash will run it

#!/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),例如这种方法(结合哈里·约翰斯顿的建议):

You can include more complex code by commenting the code blocks with a distinct prefix, then having each language filter out its own code and eval it (usual security caveats apply with eval), e.g. with this approach (incorporating suggestion from 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