1

1 つの Linux マシンですべての USB をアンバインド/バインドするスクリプトを作成する必要があります。

このためには、次を実行する必要があります。

lsusb -t は以下を返します:

root@lsdg7sd-fc:~# lsusb -t
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ohci_hcd/10p, 12M
    |__ Port 4: Dev 2, If 0, Class=vend., Driver=ftdi_sio, 12M
    |__ Port 6: Dev 4, If 0, Class=HID, Driver=usbhid, 1.5M
    |__ Port 6: Dev 4, If 1, Class=HID, Driver=usbhid, 1.5M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci_hcd/10p, 480M

さて、この例では、次を実行する必要があります。

 // disable the bus 1, port 1
 echo '2-4' | tee /sys/bus/usb/drivers/usb/unbind
 // disable the bus 1, port 2
 echo '2-6' | tee /sys/bus/usb/drivers/usb/unbind
 // enable the bus 1, port 1
 echo '2-4' | tee /sys/bus/usb/drivers/usb/bind
 // enable the bus 1, port 2
 echo '2-6' | tee /sys/bus/usb/drivers/usb/bind

スクリプトを作成してこれを達成するために(私はLinuxに非常に慣れていません)、次のことを行いました。

#!/bin/bash

lsusb -t | awk '{

bus="";
if($1=="|__")
      print "Child USB Port: ",$3;
else if ($1=="/:") {
      print $3;
      var= $(echo $3 | grep -o "[1-9]");
      echo $var;
}
}'

var=`echo "02.Port" | grep -o "[1-9]"`;
echo $var;
var=`echo "02.Port" | grep -o "[0-9]\{2\}"`;
echo $var;

var を設定するために、考えられるすべての組み合わせを試しました。私はいつもエラーが発生します。

awk: line 8: syntax error at or near grep

誰かが解決策または別のアプローチを提案できますか?

読んでくれてありがとう。

- - - - - - - - - - - アップデート

Ed Morton に感謝します。入力はコマンド lsusb -t: の結果です (私の最後で)

/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ohci_hcd/10p, 12M
    |__ Port 4: Dev 2, If 0, Class=vend., Driver=ftdi_sio, 12M
    |__ Port 6: Dev 4, If 0, Class=HID, Driver=usbhid, 1.5M
    |__ Port 6: Dev 4, If 1, Class=HID, Driver=usbhid, 1.5M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci_hcd/10p, 480M

そして、この情報を解析して BUS 番号とポート番号を取得したいと考えています。したがって、出力は次のようになります。

2-1
2-4
2-6
2-6
1-1

ただし、「子」ポートのみが必要なので、次の出力が必要です。

2-4
2-6
2-6

再度、感謝します!

4

2 に答える 2

1

shell は、UNIX ツールを呼び出すための環境であり、これらの呼び出しを順序付ける言語を備えています。

grep は、正規表現に一致するファイル (またはパイプ) から行を出力する UNIX ツールです。

awk は、テキストを処理するための標準的な汎用 UNIX ツールです。

これらは、独自の言語/構文を持つ 3 つの完全に異なるツールです。

シェルから grep を呼び出して正規表現を見つけ、一致する行を出力します。

シェルから awk を呼び出して、より複雑なテキスト操作操作を実行します。これには、grep が実行できるものを含む場合と含まない場合があります。

awk から grep を呼び出すことはできず、grep から awk を呼び出すこともできません。

非常にまれな状況で awk からシェルを呼び出すことができますが、それが役立つ場合もありますが、grep からシェルを呼び出すことはできません。

質問にサンプル入力を投稿しました。その入力でツールを実行した結果として取得したい特定の出力を表示するように更新してください。それを行うためのツールを作成するのに役立ちます。

参考までに、awk スクリプトが echo や grep などでやろうとしていることを実行するための正しい awk 構文を次に示します。

$ cat tst.awk
{
    if (/\|__/) {
        print "Child USB Port: ",$3
    }
    else {
        print $3
        var = $3
        gsub(/[^[:digit:]]/,"",var)
        print var
    }
}
$
$ awk -f tst.awk file
02.Port
02
Child USB Port:  4:
Child USB Port:  6:
Child USB Port:  6:
01.Port
01

あなたの更新された質問を考えると:

$ cat tst.awk
{
    var = $3+0
    if (/\/:/) {
        bus = var
    }
    else {
        print bus "-" var
    }
}
$
$ awk -f tst.awk file
2-4
2-6
2-6

それを標準出力だけでなくいくつかのファイルに移動したい場合は、後続のエコー+パイプ+ティーの代わりに必要なのは次のとおりです。

BEGIN{
    path   = "/sys/bus/usb/drivers/usb/"
    unbind = path "unbind"
    bind   = path "bind"
}
{
    var = $3+0
    if (/\/:/) {
        bus = var
    }
    else {
        busPort = bus "-" var
        print busPort
        print busPort > unbind
        print busPort > bind
    }
}

すでに処理したバスとポートの組み合わせに対してアクションを繰り返すのは無意味に思われるため (たとえば、2 番目の 2-6):

BEGIN{
    path   = "/sys/bus/usb/drivers/usb/"
    unbind = path "unbind"
    bind   = path "bind"
}
{
    var = $3+0
    if (/\/:/) {
        bus = var
    }
    else {
        busPort = bus "-" var
        if (!seen[busPort]++) {
            print busPort
            print busPort > unbind
            print busPort > bind
        }
    }
}
于 2014-11-04T17:01:46.137 に答える
0

内部で変数を定義することはできませんawk

var= $(echo $3 | grep -o "[1-9]"

次のようにします。

awk -v var=$(echo $3 | grep -o "[1-9]" '{print var}' file

awkPS と の両方を使用する必要がある理由がわかりませんgrep

于 2014-11-04T15:59:27.593 に答える