Bash Scripting - 从Systemd

时间:2017-07-01 14:59:25

标签: linux bash debian

我一直在谷歌搜索很多,但我没有找到任何信息来帮助我完成任务。也许它不可能。我正在使用覆盆子Pi上的Raspbian发行版,但我认为它与任何bash脚本相关。

我创建了udev规则和一个systemd服务,执行我在系统检测到插入usb的谷歌手机时写的bash脚本(例如插入nexus 4,5 6P等)。一切正常。您插入手机,我的脚本将执行并使用fastboot获取设备产品名称,然后将相应的twrp图像闪存到手机上的恢复分区(twrp是手机的自定义恢复操作系统)。

如果我在终端手动执行bash脚本,您将进行用户交互。回应信息,什么不是。我有一个5秒倒计时器,让用户有机会在检测到设备后停止执行。这也有效。

我的问题是:当脚本由systemd执行时,它在它自己的虚拟终端或其他任何情况下,如果您在控制台上看不到脚本中的任何内容,并且脚本无法看到任何用户输入(例如击键)取消。

我想知道,如果您坐在控制台上让我的脚本开始显示5秒倒计时警告并允许用户取消,有没有办法?

我目前在无头模式下设置了raspberry pi,因此它启动到控制台就可以了。它不会启动任何图形环境。我通常会在树莓PI中使用它来处理它。所以当我ssh并执行w命令时,我看到我的tty是/ pts / 0。

是否可以让我的脚本输出并读取当前控制台的任何键击?我希望这是有道理的。

我最终在我的脚本中创建了一个函数,我可以调用它来回应所有活跃的,开放的tty,但我不知道如何阅读。我认为可能有更优雅的方式实现我正在做的事情。提前感谢任何人提供的帮助或建议。我将把代码和输出放在下面。

保罗。

USER     TTY      FROM             LOGIN@   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

1 个答案:

答案 0 :(得分:0)

答案很简单:你做不到。如果可以,你不应该。

写入所有终端很容易; wall会为您做到这一点。但是,已经有一个进程读取您的终端输入,这是您的shell(bash如果一切都是默认值)。因此,如果您希望第二个进程从同一个终端读取,您将遇到以下问题:您键入的某些字符将转到脚本,而某些字符转到shell。也许一个例子将证明这个问题:

您在ssh会话中键入rm -rf /a,手机已连接。几乎所有内容都被shell捕获,但是你的脚本捕获了a,当你点击回车时,你会收到警告:在/./ / p>上递归操作是危险的。

您可能想要探索其他选项;例如,dancer2网络应用程序。