[英]Is it possible to call a bash shell script using supervisord?
[英]Is it possible to write one script that runs in bash/shell and PowerShell?
我需要創建一個集成腳本來設置一些環境變量,使用 wget 下載文件並運行它。
挑戰在於它必須是可以在 Windows PowerShell 和 bash / 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
所以我想知道這兩個腳本是否可以以某種方式合並並在任一平台上成功運行?
我一直在嘗試找到一種方法將它們放在同一個腳本中並讓 bash 和 PowerShell.exe 忽略錯誤,但這樣做沒有成功。
有什么猜測嗎?
有可能的; 我不知道這有多兼容,但 PowerShell 將字符串視為文本,它們最終出現在屏幕上,Bash 將它們視為命令並嘗試運行它們,並且兩者都支持相同的函數定義語法。 因此,將函數名稱放在引號中,只有 Bash 會運行它,將“exit”放在引號中,只有 Bash 會退出。 然后編寫PowerShell代碼。
注意。 這是有效的,因為兩個 shell 中的語法重疊,並且您的腳本很簡單 - 運行命令並處理變量。 如果您嘗試對任一語言使用更高級的腳本(if/then、for、switch、case 等),另一個可能會抱怨。
將其保存為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
#!/usr/bin/env sh
true --% ; : '
<#'
#
# sh part
#
echo "hello from bash/dash/zsh"
echo "do whatver you want just dont use #> directly"
echo "e.g. do #""> or something similar"
# end bash part
exit #>
#
# powershell part
#
echo "hello from powershell"
echo "you literally don't have to escape anything here"
語法高亮告訴我們幾乎整個故事
檸檬綠色部分( ; : '
)只是參數
淡藍色很特別
<#
是評論的開始
對於 bash,它完全不同。
--%
並不特殊,它只是一個參數( true
忽略參數)
但是;
很特別,這就是命令的結尾
然后:
實際上是“什么都不做”的shell命令
然后'
開始一個在下一行結束的字符串參數
好吧,這要歸功於
--%
),這讓我們不能在 powershell 中啟動字符串,而在 bash 中啟動字符串<#
和#>
幾乎沒有。 Powershell 合法地沒有缺點。 Bash 警告很容易修復,而且非常罕見
"#>"
更改為"#"">"
' blah #> '
到' blah #''> '
。#>
並且由於某種原因您不能更改該評論(這就是我所說的非常罕見的意思),您實際上可以只使用#>
,您只需要添加重新添加前兩行(例如true --%
等)就在您的#>
評論之后#
刪除字符串的一部分(我敢打賭,大多數人甚至不知道這是一個 bash 功能)。 下面的示例代碼https://man7.org/linux/man-pages/man1/bash.1.html#EXPANSION var1=">blah" echo ${var1#>} # ^ removes the > from var1
為了解決這個問題,還有其他方法可以從字符串的開頭刪除字符,請改用它們。
跟進Jeff Hykin 的回答,我發現第一行雖然在 bash 中很開心,但在 PS 中產生了這個輸出。 請注意,它仍然功能齊全,只是嘈雜。
true : The term 'true' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling
of the name, or if a path was included, verify that the path is correct and try again.
At C:\Users\jp\scratch\envar.ps1:4 char:1
+ true --% ; : '
+ ~~~~
+ CategoryInfo : ObjectNotFound: (true:String) [], CommandNotFoundException
hello from powershell
我正在嘗試更改第一行:
true --% ; : '
<#'
到:
echo --% > /dev/null ; : ' | out-null
<#'
在非常有限的測試中,這似乎在 bash 和 powershell 中工作。 作為參考,我是在“采購”腳本而不是“調用”它們,例如. env.ps1
. env.ps1
在 bash 和. ./env.ps1
. ./env.ps1
在 powershell 中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.