質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.53%

  • C

    4382questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • Linux

    4370questions

    Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

  • Raspberry Pi

    1046questions

    Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Linux(RaspberryPI)に既についているUSBメモリの認識場所(/dev/sda1)を得たい。

解決済

回答 1

投稿

  • 評価
  • クリップ 2
  • VIEW 156

cafe_takai

score 19

前提・実現したいこと

C言語を用いて、Linux(RaspberryPI)に既についているUSBメモリの認識場所(/dev/sda1)を得たいのですが方法が分かりません。

発生している問題

USBメモリのデバイスモード(/dev/bus/usb/002/002)は得られるのですが、認識場所(/dev/sda1)が得られません。

該当のソースコード

#include <libudev.h>
#include <stdio.h>
#include <stdlib.h>

/* メイン関数 */
int main(void) {
  struct udev *udev;
  struct udev_enumerate *enumerate;
  struct udev_list_entry *devices;

  udev = udev_new();
  if (!udev) {
      printf("Can't create udev\n");
      exit(1);
  }

  // 現時点でどのデバイスにプラグインしているか?
  enumerate = udev_enumerate_new(udev);
  udev_enumerate_add_match_subsystem(enumerate, "scsi");
  udev_enumerate_add_match_property(enumerate, "DEVTYPE", "scsi_device");
  udev_enumerate_scan_devices(enumerate);

  devices = udev_enumerate_get_list_entry(enumerate);
  struct udev_list_entry *entry;

  // インストールされているものを列挙する
  udev_list_entry_foreach(entry, devices) {
      const char *path = udev_list_entry_get_name(entry);
      struct udev_device *scsi = udev_device_new_from_syspath(udev, path);
      struct udev_device *usb = udev_device_get_parent_with_subsystem_devtype(scsi, "usb", "usb_device");
      const char *node;
      if (usb) {
          node = udev_device_get_devnode(usb);
          printf("usb = %s:%s:%s, scsi = %s / devnode = :%s:%s\n",
                  udev_device_get_sysattr_value(usb, "idVendor"),
                  udev_device_get_sysattr_value(usb, "idProduct"),
                  node,
                  udev_device_get_sysattr_value(scsi, "vendor"),
                  udev_device_get_devnode(usb),
                  udev_device_get_devnode(scsi)
                );
      }
      udev_device_unref(scsi);
  }
  udev_enumerate_unref(enumerate);
}

出力結果

usb = 0411:023a:/dev/bus/usb/002/002, scsi = BUFFALO  / devnode = :/dev/bus/usb/002/002:(null)

試したこと

udev_device_get_devnodeやudev_device_get_sysattr_valueのパラメータを色々と変えたのですが、ダメでした。

どなた様か、ご教示いただけましたら幸いです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

/sys/dev/block/ 以下のシンボリックリンクのリンク先パスを見るとわかるかもしれません。

$ ls -l /sys/dev/block/
(表示例)
lrwxrwxrwx 1 root root 0 Mar  7 18:55 8:0 -> ../../devices/pci0000:00/0000:00:1f.2/ata4/host3/target3:0:0/3:0:0:0/block/sda
lrwxrwxrwx 1 root root 0 Mar  7 18:55 8:1 -> ../../devices/pci0000:00/0000:00:1f.2/ata4/host3/target3:0:0/3:0:0:0/block/sda/sda1
lrwxrwxrwx 1 root root 0 Mar  7 18:55 8:16 -> ../../devices/pci0000:00/0000:00:14.0/usb3/3-3/3-3:1.0/host4/target4:0:0/4:0:0:0/block/sdb
lrwxrwxrwx 1 root root 0 Mar  7 18:55 8:17 -> ../../devices/pci0000:00/0000:00:14.0/usb3/3-3/3-3:1.0/host4/target4:0:0/4:0:0:0/block/sdb/sdb1
lrwxrwxrwx 1 root root 0 Mar  7 18:55 8:18 -> ../../devices/pci0000:00/0000:00:14.0/usb3/3-3/3-3:1.0/host4/target4:0:0/4:0:0:0/block/sdb/sdb2
lrwxrwxrwx 1 root root 0 Mar  7 18:55 8:2 -> ../../devices/pci0000:00/0000:00:1f.2/ata4/host3/target3:0:0/3:0:0:0/block/sda/sda2
lrwxrwxrwx 1 root root 0 Mar  7 18:55 8:3 -> ../../devices/pci0000:00/0000:00:1f.2/ata4/host3/target3:0:0/3:0:0:0/block/sda/sda3
lrwxrwxrwx 1 root root 0 Mar  7 18:55 8:4 -> ../../devices/pci0000:00/0000:00:1f.2/ata4/host3/target3:0:0/3:0:0:0/block/sda/sda4
lrwxrwxrwx 1 root root 0 Mar  7 18:55 8:5 -> ../../devices/pci0000:00/0000:00:1f.2/ata4/host3/target3:0:0/3:0:0:0/block/sda/sda5
lrwxrwxrwx 1 root root 0 Mar  7 18:55 8:6 -> ../../devices/pci0000:00/0000:00:1f.2/ata4/host3/target3:0:0/3:0:0:0/block/sda/sda6
lrwxrwxrwx 1 root root 0 Mar  7 18:55 8:7 -> ../../devices/pci0000:00/0000:00:1f.2/ata4/host3/target3:0:0/3:0:0:0/block/sda/sda7

  ※sdb が USB ストレージでパーティション 2

(2019/03/07 23:11) 追記

リンク先パスに usb という文字列があるものを抜き出せばいいのでは? という意図でした。
コマンドなら以下のように。

$ ls -l /sys/dev/block/* | sed -n '/usb/s|^.*/||p'
sdb
sdb1
sdb2


あるいは、ファイルシステムにラベルが付いているのであれば、lsblk -l -o NAME,LABEL などでわかると思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/07 21:48

    ご回答ありがとうございます。C言語にすると、次の通りでしょうか。

    #include <libudev.h>
    #include <stdio.h>
    #include <stdlib.h>

    /* メイン関数 */
    int main(void) {

    char buff[1024];
    FILE *fp = popen("ls -l /sys/dev/block/", "r");
    while (fgets(buff, sizeof(buff), fp)) {
    printf("result: %s", buff);
    }
    pclose(fp);
    }

    得られた中から、/dev/sd*...を探せば可能だと思うのですが、直接に/dev/sda1を得られる方法はないでしょうか?

    USBを抜き差しする折、sda1 / sdb1 / sdc1 ....となってしまうので、得られた結果の中から順に探すという方法もあると思うのですが、いくつまで探せばいいのかという課題もあいますし、直接に抽出できたらと思うのです。

    生意気申しあげ申し訳ありません。アドバイスありましたらお願い申しげます。

    キャンセル

  • 2019/03/08 06:29

    アドバイスありがとうございます。

    詳細コマンドありがとうございます。頂戴しました内容で対応させていただきます。

    ご教示賜り、誠にありがとうございます。

    キャンセル

同じタグがついた質問を見る

  • C

    4382questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • Linux

    4370questions

    Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

  • Raspberry Pi

    1046questions

    Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。