2017-07-01 105 views
1

我一直在谷歌搜索了很多,但我沒有找到任何信息來幫助我完成我的任務。也許它不可能。我正在Raspbian發行版上使用Raspbian發行版,但我認爲它與任何bash腳本相關。Bash腳本 - 從Systemd啓動腳本時的用戶交互

我已經創建了udev規則和systemd服務來執行我在系統檢測到插入usb的谷歌手機(例如插入nexus 4,5,6P等)時編寫的bash腳本。它一切正常。您插入手機,我的腳本將執行並使用fastboot獲取設備產品名稱,然後將相應的twrp映像閃存到手機上的恢復分區(twrp是針對手機的自定義恢復操作系統)。

如果我在終端手動執行bash腳本,你將有用戶交互。迴應信息和什麼不是。我有一個5秒倒數計時器給用戶在檢測到設備後停止執行的機會。這也起作用。

我的問題是這樣的:當systemd執行它的腳本時,它會在它自己的虛擬終端中執行,或者如果你在控制檯上,你不會看到任何腳本和腳本不能看到任何用戶輸入(例如鍵擊)取消。

我想知道,如果您坐在控制檯上爲我的腳本開始顯示5秒倒計時警告並允許用戶取消,有沒有辦法?

我目前有在無頭模式下的樹莓派設置,所以它引導到控制檯和多數民衆贊成在它。它不啓動任何圖形環境。我通常會和樹莓派一起工作。所以當我ssh進入並執行w命令時,我看到我的tty是/ pts/0。

是否有可能讓我的腳本輸出並讀取當前控制檯中的任何鍵擊?我希望這是有道理的。

我最終在我的腳本中創建了一個函數,我可以調用它來回顯所有活動的,打開的tty,但我不知道如何讀入。而且我認爲可能有一種更優雅的方式來實現我在做。預先感謝任何人可以提供的幫助或建議。我會在下面放置代碼和輸出。

Paul。

USER  TTY  FROM    [email protected] IDLE JCPU PCPU WHAT 
pi  tty1      18:22 1:08m 1.18s 0.92s -bash 
pi  pts/0 fe80::187c:321f: 18:49 1.00s 2.98s 0.05s w 

我的udev規則

# Google 
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", MODE:="0666", GROUP:="plugdev", TAG+="systemd", ENV{SYSTEMD_WANTS}+="load-fastboot-flasher.service" 

我systemd服務單位檔案

[Unit] 
Description=Google Device TWRP Recovery 
After=multi-user.target 

[Service] 
Type=idle 
User=pi 
ExecStart=/home/pi/fastboot-twrp/fastboot-twrp-flash.sh > /dev/null & 
StandardOutput=console 

[Install] 
WantedBy=multi-user.target 

最後我bash腳本

#!/bin/bash 

###################################################################################### 
# Our function that performs the flash after a device was detected. 
###################################################################################### 
fastboot-test() { 
GOOGLEDEVICENAME=`fastboot getvar product 2>&1 | grep "product:" | awk '{print $2}'` 
if [[ "$GOOGLEDEVICENAME" != "" ]]; then 
    echoall "Device Product_Name: $GOOGLEDEVICENAME" 
    if [ ! -d "$GOOGLEDEVICENAME" ]; then 
     # Control will enter here if $DIRECTORY doesn't exist. 
     echoall "Error! Device folder & recovery image dont exist. Aborting!" 
     echoall "" 
     echoall "Please create a folder using the same product name as your device in the folder" 
     echoall "that this script resides in and place your twrp image in this new folder." 
     echoall "e.g. for a Nexus 4 make a folder called mako with your twrp image inside it." 
     echoall "" 
     exit 1 
    fi 
    cd $GOOGLEDEVICENAME 
    echoall "Selecting twrp image: " $PWD/twrp* 
    sleep 1 
    echoall "" 
    fastboot flash recovery $PWD/twrp* 
    echoall "" 
    echoall "twrp recovery image flash complete!" 
    echoall "Enjoy your fishing.... ;-)" 
    echoall "" 
else 
    echoall "No connected Google devices" 
fi 
} 

###################################################################################### 
# Our function to print output to all currently open consoles (e.g. type w a terminal to see users) 
###################################################################################### 
echoall() { 
for PTS in $(w |grep -o pts/.) ; do echo $1 $2 $3 >>/dev/$PTS; echo $1 $2 $3 >>/home/pi/load-fastboot-flasher.log; done 
} 



###################################################################################### 
# START 
###################################################################################### 
#set +x 
echoall "" 
echoall "$(date)" 
echoall "" 
echoall "Google device detected. Press C then ENTER to cancel TWRP recovery flash in 5 seconds" 
COUNT=5 
while ((COUNT > 0)) 
#This is our 5 sec timer. 
do 
    read -t 1 -n 1 -r 
    if [[ $REPLY == ^[Cc]$ ]]; then 
     Exit 0 
    fi 
    sleep 1 
    ((COUNT --)) 
    echoall $COUNT 
done 
echoall "" 
echoall "" 
#set -x 

DETECTED=`fastboot devices | awk '{print $2}'` 
if [[ "$DETECTED" == "fastboot" ]]; then 

    #Save the current working directory 
    RESTOREPATH=`pwd` 

    #Change the current working directory to the directory that this script resides in 
    cd $(dirname $(readlink -f $0)) 
    echoall "changed working directory to: "$PWD 
    echoall "" 
    # 

    echoall "Device detected: Yes" 
    fastboot-test 
    cd $RESTOREPATH 
    echoall "changed working directory to: "$PWD 
    echoall "" 
    echoall "### END TWRP FLASH ###" 
    echoall "" 
    for PTS in $(w |grep -o pts/.) ; do echo -ne '\n' >>/dev/$PTS; done 
    exit 
else 
    echoall "Error! Fastboot not properly detecting Google device." 
fi 
+0

你可能會考慮[systemd user mode](https://wiki.archlinux.org/index.php/Systemd/User)。我不知道的是如何在這種情況下插入udev。 – ldav1s

回答

0

答案很簡單:你不能。如果可以的話,你不應該這樣做。

寫入所有終端很容易; wall將爲您做到這一點。但是,已經有一個讀取終端輸入的進程,那就是你的shell(bash,如果一切都是默認的)。所以如果你想讓第二個進程從同一個終端讀取,你將會遇到一些問題,你輸入的一些字符將會被轉到腳本,並且一些腳本會返回到shell。也許一個例子會證明這個問題:

你在你的ssh會話中輸入rm -rf /a並且手機被連接。幾乎所有東西都被shell捕獲,但腳本捕獲到a,當你敲入回車時,你會得到警告,認爲在/上遞歸操作是危險的。

您可能想要探索其他選項;例如dancer2網絡應用程序。

+0

感謝您的回覆。是的,我認爲它可能不是一個明智的舉動,你的榜樣證明它有多危險。謝謝。 – user8241392

+0

我只是另有想法。我可以讓我的腳本創建一個新的tty並切換到該狀態,然後完成切換回原始的tty? – user8241392

+0

但是這會產生同樣的問題。假設這是可能的,無論是從終端讀取的兩個進程還是兩個終端從您鍵入的內容讀取,問題都是一樣的。 –