Linux

Linux - 掛載命令返回零/0 但不起作用

  • September 22, 2020

聽起來很奇怪,我有一個由udev 規則觸發的 shell 腳本,用於將連接的 USB 設備掛載到系統文件樹。該腳本在 USB 設備連接到系統時執行,因此規則似乎很好。我通過 syslog 監控腳本的進度,它也很順利,甚至mount 命令返回零,它說:

root[1023]: mount: /dev/sda1 mounted on /media/partitionlabel.

但是最後設備沒有掛載,它沒有在*/etc/mtab - /proc/mounts - findmnt - mount中列出。如果我在設備上執行umount*,它還會說,設備未安裝。

但是,如果我從終端以 root 身份手動執行腳本,那麼它可以完美執行並且設備會被掛載,但當它由udev執行時則不會。

我在腳本的開頭添加了 8 秒的睡眠時間,以確保它不是時間問題,並從規則文件名中刪除了數字,以確保udevd將新規則放在規則隊列的底部,並且腳本會執行其他系統規則,但沒有成功。

系統日誌:

(在連接設備之後)

kernel: usb 1-1.2: new high-speed USB device number 12 using dwc_otg
kernel: usb 1-1.2: New USB device found, idVendor=058f, idProduct=6387
kernel: usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
kernel: usb 1-1.2: Product: Mass Storage
kernel: usb 1-1.2: Manufacturer: Generic
kernel: usb 1-1.2: SerialNumber: 24DCF568
kernel: usb-storage 1-1.2:1.0: USB Mass Storage device detected
kernel: scsi host6: usb-storage 1-1.2:1.0
kernel: scsi 6:0:0:0: Direct-Access     Generic  Flash Disk       8.07 PQ: 0 ANSI: 4
kernel: sd 6:0:0:0: [sda] 1968128 512-byte logical blocks: (1.00 GB/961 MiB)
kernel: sd 6:0:0:0: [sda] Write Protect is off
kernel: sd 6:0:0:0: [sda] Mode Sense: 23 00 00 00
kernel: sd 6:0:0:0: [sda] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
kernel:  sda: sda1
kernel: sda: p1 size 1968126 extends beyond EOD, enabling native capacity
kernel:  sda: sda1
kernel: sda: p1 size 1968126 extends beyond EOD, truncated
kernel: sd 6:0:0:0: [sda] Attached SCSI removable disk
root[1004]: /usr/local/sbin/udev-auto-mount.sh - status: started to automount sda1
root[1019]: /usr/local/sbin/udev-auto-mount.sh - status: Device Label is partitionlabel and Filesystem is vfat.
root[1021]: /usr/local/sbin/udev-auto-mount.sh - status: mounting the device sda1 by filesystem vfat to /media/partitionlabel.
root[1023]: mount: /dev/sda1 mounted on /media/partitionlabel.
root[1024]: /usr/local/sbin/udev-auto-mount.sh status: mount command proceed for vfat, retval is 0
root[1025]: /usr/local/sbin/udev-auto-mount.sh - status: succeed!

配置:

/etc/udev/rules.d/local-rules:

udev中定義的規則是:

# /etc/udev/rules.d/local-rules
ENV{ID_BUS}=="usb",     ACTION=="add",  ENV{DEVTYPE}=="partition",      \
         RUN+="/usr/local/sbin/udev-automounter.sh %k $ENV{ID_FS_LABEL_ENC}"

udev-auto-mount.sh

該腳本由 udev 規則中定義的另一個腳本開始。它非常直接,它創建掛載點目錄並使用其文件系統類型和一些正常選項將 USB 設備掛載到掛載點。我在 mount 命令中添加了“-v”選項,使其更加詳細,並將所有輸出重定向到 syslog,所以我可以看到它是如何執行的,但它並沒有說太多。

#!/bin/sh
## /usr/local/sbin/udec-auto-mount.sh
##

logger -s "$0 - status: started to automount ${1}"
DEVICE=$1
sleep 8 

#...
#...
# Checking inputs, getting filesystem type (ID_FS_TYPE), partition label
# (ID_FS_LABEL) and ...

mkdir "/media/${ID_FS_LABEL}"


logger -s "$0 - status: mounting the device ${DEVICE} by filesystem ${ID_FS_TYPE} to /media/${ID_FS_LABEL}."
case $ID_FS_TYPE in
   vfat)   mount -v -t vfat -o sync,noatime,nosuid,nodev /dev/${DEVICE} "/media/${ID_FS_LABEL}" 2>&1 | logger
       let retVal=$?
       logger -s "$0 status: mount command proceed for vfat, retval is ${retVal}"
       ;;

   *)  mount -v -t auto -o sync,noatime /dev/${DEVICE} "/media/${ID_FS_LABEL}"
       ;;
esac
if [ ${retVal} -eq 0 ]; then
   logger -s "$0 - status: succeed!"
   exit 0
else
   logger -s "$0 Error: unable to mount the device ${DEVICE}, retval is ${retVal}"
   rmdir "/media/${ID_FS_LABEL}"
fi

exit 0

也許它有幫助:

有時,在腳本無法掛載 USB 設備後,當我分離設備時,系統日誌會出現一些錯誤,例如:

kernel: usb 1-1.2: USB disconnect, device number 11
systemd-udevd[143]: error: /dev/sda: No such file or directory
systemd-udevd[977]: inotify_add_watch(7, /dev/sda, 10) failed: No such file or directory

編輯:

這是“安裝”版本:

$ mount -V:
mount from util-linux 2.27.1 (libmount 2.27.0: assert, debug)

在帶有 systemd 的系統上,當您重新格式化分區並嘗試重新掛載它時,可能會遇到此問題。

我將磁碟從加密移動到未加密,導致 systemd 生成的mnt-disk.mount 到(其中 mnt-disk 是 /etc/fstab 的掛載路徑)引用不再存在的舊路徑,導致mount出現故障。

只是做systemctl daemon-reload然後做安裝就可以了。

序列

mount ... | logger
rc=$?

沒有按預期工作:管道的返回值是該管道中最後一個元素的返回值。

$> false | true; echo $?
0

如果您使用 bash,請嘗試PIPESTATUS

$> false | true; echo $? ${PIPESTATUS[0]}
0 1
$> true | false; echo $? {PIPESTATUS[0]}
1 0

PIPESTATUS是一個數組變數。bash 手冊頁中的詳細資訊。其他 shell 可能有類似的東西PIPESTATUS

引用自:https://unix.stackexchange.com/questions/204906