是否可以從非 bash 腳本運行內建 bash?

是否可以從非 bash 腳本運行內建 bash?

例如,是否可以history -w從 ruby​​ 腳本執行底層 bash shell?
或者更好的是,是否可以運行僅知道其 pid 的 bash shell 的內建命令?

我發現的唯一方法是捕獲信號trap "history -w" SIGUSR1,然後發送信號到進程,但我不確定這是一個好的做法,並且 bash 不使用 USR1,這樣我也可以執行最多 2 個命令(USR1 和 USR2) 。我必須在使用 trap 之前定義它。

我使用的是 Mac,所以沒有 SIGRTMIN..SIGRTMAX。

為什麼我需要這個:

我創建了 ruby​​ shell 腳本dt,它使用相同的工作目錄在當前旁邊打開新選項卡,然後我寫了newTabHere.app可以做同樣的事情,但即使選項卡正忙於運行某些東西(我稱之為使用火花)。但是,如果重複選項卡中的歷史記錄也相同並且dt我可以使用,那就更好了alias dt='history -w; dt',但是我怎麼能做到這一點呢newTabHere.app

答案1

除了在標準輸入上輸入之外,沒有現成的方法可以讓 shell 執行指令。最簡單的事情是讓 bash 檢查某個文件,或者運行,作為(在每個提示之前執行的命令)history -w的一部分。PROMPT_COMMAND

我認為你所追求的其實是Bash 終端機視窗之間的即時歷史記錄匯出,也許更好的 bash 歷史記錄

您也可以考慮使用桀騁(在大多數 Linux/OSX/其他 unix 軟體包儲存庫中可用)及其inc_append_historyshare_history 選項

答案2

對於這個特定的用例,我建議只添加history -w到您的PROMPT_COMMAND(或在由此調用的 shell 函數中)。

更一般地說,我建議為外部請求的命令建立一個佇列,並使用PROMPT_COMMAND它們來運行它們:

run_prompt_queue() {
  local f
  for f in ~/.bash_queue.d/$$-*
  do
    [[ -f $f ]] || continue # still works without nullglob
    . "$f"
    rm -fv "$f"
  done
}
PROMPT_COMMAND+=$'\n run_prompt_queue'
rm -v "$HOME/.bash_queue.d/$$-"* # clear random leftovers when PID is recycled

然後在 Python 腳本中建立一個包含要執行的命令的文件,然後將其重命名為sprintf("%s/.bash_queue.d/%u,%s", sys.env("HOME"), pid_of_bash, your_unique_suffix).

pid_of_bash可能是sys.getppid()或 ,sys.getsid()但是這可能會根據腳本的嵌套級別而有所不同。

顯然,您可以選擇自己的檔案命名約定,但我強烈建議您包含目標 shell 的 PID,至少作為一個選項。

如果您不關心哪個特定 shell,您也可以根據 pgrp、sid、tty、一天中的時間等觸發)

重要提示:確保沒有其他人可以寫入您的佇列目錄。

相關內容