在 shell 腳本之間交換輸入數據

在 shell 腳本之間交換輸入數據

我有一個簡單的 shell 腳本可以在 Android adb shell 中運行。

while true; do
    read var1
    echo $var1 > /data/local/tmp/debug.txt
    am force-stop $var1
done

如果我在原始 shell 實例的控制台中輸入一個值,它就可以正常運作。但是如果我打開另一個 adb shell 並嘗試將資料傳遞到第一個進程:

echo "com.package.name" > /proc/XXXX/fd/0

其中 XXXX 是第一個 shell 的 pid,我只看到字串「com.package.name」到達第一個 shell 中read,但偵錯echo行和am行都沒有執行。那是腳本似乎在等待某些東西,也許是換行符,但是將\n-e參數和其他內容添加到第二個 shell 輸入中並沒有幫助。

如何在 shell 腳本之間正確傳遞資料?

答案1

你被通常的觀念所伏擊,那就是Linux系統中的一切都是文件。為了說明這一點,我將你的指令放在一個名為 的檔案中forever,然後找到該進程的 PID,然後

$ file /proc/25546/fd/*
  /proc/25546/fd/0:   symbolic link to `/dev/pts/12' 
  /proc/25546/fd/1:   symbolic link to `/dev/pts/12' 
  /proc/25546/fd/2:   symbolic link to `/dev/pts/12' 
  /proc/25546/fd/255: symbolic link to `/home/me/tmp/forever'
 $ file /dev/pts/12
  /dev/pts/12: character special

這表示你的文件描述符1,2,3是字元檔。現在,這是眾所周知的(例如,參見這個答案在 Unix 和 Linux 上) 那:

字元設備(也稱為字元特殊檔案)的行為類似於管道、序列埠等:對它們進行寫入或讀取是立即操作。但驅動程式對數據所做的事情是自己的事業。將一個位元組寫入字元設備可能會導致它顯示在螢幕上、在序列埠上輸出、轉換為聲音…從裝置讀取一個位元組可能會導致序列埠等待輸入,可能會傳回一個隨機數字節(/dev/urandom),...

所以你需要另一種方式來執行IPC(=進程間通訊)。在 Unix 和 Linux 上, 有 命名管道為了這。如下修改您的腳本:

#!/bin/bash

MYPIPE=/tmp/my_pipe
if [[ ! -p $MYPIPE ]]; then
     mkfifo $MYPIPE
fi

while true
do
     if read line <$pipe; then
         if [[ "$line" == 'quit' ]]; then
            break
         fi
         echo $line >> /tmp/debug.txt
     fi
done

echo "I quit"

啟動腳本;從另一種終端類型

 $ cat > /tmp/my_pipe
   My name is 
   George Washington 
    ....

從第三個終端,使用tail -f /tmp/debug.txt,您將看到剛剛在第二個終端中輸入的內容,從 重新出現/tmp/debug.txt

在安卓上,情況有點複雜,但你會發現這裡這裡有兩種不同的方法可以解決在非 root Android 裝置上建立命名管道的問題(第一種方法比第二種方法更簡單)。

相關內容