如何从 bash 脚本中 Docker 容器内的脚本 运行 获取 USB 设备信息?
How do I get USB device info from a script running within a Docker container in a bash script?
我根据 balena-storage 制作了一个 mount.sh 文件。当我通过我正在部署的 balena.io 仪表板(在其他地方可能相同)和手动 运行 脚本登录到容器时,它会起作用。当容器启动时 运行s 脚本(一个 运行s 脚本的脚本)时,它会挂起未填充的变量。我认为这是权限问题或脚本 运行ning 脚本问题。我不确定如何继续读取 USB 设备变量。
mount.sh:
# Automatically mount a USB drive by specified volume name.
# Note: make sure to have USB_VOLUME_NAME set in env vars.
# Thanks: https://github.com/balena-io-playground/balena-storage
echo "Checking for USB_VOLUME_NAME..."
echo "A"
if [[ -z $USB_VOLUME_NAME ]]; then
echo "Make sure to set environment variable USB_VOLUME_NAME in order to find a connected USB drive by that label and connect to it. Exiting..." >> /usr/src/app/mount.log
exit 1
fi
echo "B"
# Get device by label env var set in balena.io dashboard device env vars
USB_DEVICE=$(blkid -L $USB_VOLUME_NAME)
if [[ -z $USB_DEVICE ]]; then
echo "Invalid USB_DEVICE name: $USB_DEVICE" >> /usr/src/app/mount.log
exit 1
fi
echo $USB_DEVICE
echo "C"
# Get extra device info
ID_FS_TYPE=${ID_FS_TYPE:=$(/bin/udevadm info -n $USB_DEVICE | /usr/bin/awk -F "=" '/ID_FS_TYPE/{ print }')}
ID_FS_UUID_ENC=${ID_FS_UUID_ENC:=$(/bin/udevadm info -n $USB_DEVICE | /usr/bin/awk -F "=" '/ID_FS_UUID_ENC/{ print }')}
ID_FS_LABEL_ENC=${ID_FS_LABEL_ENC:=$(/bin/udevadm info -n $USB_DEVICE | /usr/bin/awk -F "=" '/ID_FS_LABEL_ENC/{ print }')}
MOUNT_POINT=/mnt/$USB_VOLUME_NAME
echo $ID_FS_TYPE
echo $ID_FS_UUID_ENC
echo $ID_FS_LABEL_ENC
echo $MOUNT_POINT
echo "D"
# Bail if file system is not supported by the kernel
if ! /bin/grep -qw $ID_FS_TYPE /proc/filesystems; then
echo "File system not supported: $ID_FS_TYPE" >> /usr/src/app/mount.log
exit 1
fi
echo "E"
# Mount device
if /bin/findmnt -rno SOURCE,TARGET $USB_DEVICE >/dev/null; then
echo "Device $USB_DEVICE is already mounted!" >> /usr/src/mount.log
else
echo "Mounting - Source: $USB_DEVICE - Destination: $MOUNT_POINT" >> /usr/src/app/mount.log
/bin/mkdir -p $MOUNT_POINT
/bin/mount -t $ID_FS_TYPE -o rw $USB_DEVICE $MOUNT_POINT
fi
echo "F"
当容器 运行 执行脚本时,它卡在“D”之后,ID_FS_TYPE、ID_FS_UUID_ENC 和 ID_FS_LABEL_ENC 为空(这是一个很好的理由挂)。
输出:
Checking for USB_VOLUME_NAME...
A
B
/dev/sda1
C
/mnt/MYDRIVE
D
我的dockerfile.template:
FROM balenalib/%%BALENA_MACHINE_NAME%%-node
# Enable udev for detection of dynamically plugged devices
ENV UDEV=on
COPY udev/usb.rules /etc/udev/rules.d/usb.rules
# Install dependencies
RUN install_packages util-linux
WORKDIR /usr/src/app
# Move scripts used for mounting USB
COPY scripts scripts
RUN chmod +x scripts/*
# server.js will run when container starts up on the device
CMD ["/bin/bash", "/usr/src/app/scripts/start.sh"]
start.sh:
echo "Mounting USB drive..."
cd /usr/src/app/scripts
/bin/bash mount.sh
# It won't get this far while the script above hangs.
echo "Starting server..."
cd /usr/src/app
/usr/local/bin/yarn run serve
我可以确认当 运行手动从容器中运行时一切正常:
cd /usr/src/app/scripts
/bin/bash mount.sh
输出:
Checking for USB_VOLUME_NAME...
A
B
/dev/sda1
C
vfat
BE23-31BA
MYDRIVE
/mnt/MYDRIVE
D
E
F
(and the drive mounted)
如何解析空变量?
总是引用每个shell你使用的变量。 (除非您完全确定自己在做什么,以及如果变量值为空或包含 spaces 时您期望发生什么。)
不引用,当你
/bin/grep -qw $ID_FS_TYPE /proc/filesystems
和 $ID_FS_TYPE
是空的,这个词只是从命令行中省略了,所以你得到
/bin/grep -qw /proc/filesystems
将 /proc/filesystems
用作正则表达式,并尝试通过其标准输入进行 grep;这会导致您看到明显的挂起。
如果你引用它:
/bin/grep -qw "$ID_FS_TYPE" /proc/filesystems
它将获得一个空字符串作为正则表达式参数和一个文件名作为输入参数,这将成功(但不会挂起)。
出于类似的原因,如果 $USB_VOLUME_NAME
未设置,我希望您会收到 shell 语法错误,并且如果该变量名称具有 [=36],则整个脚本将表现得很奇怪=]在里面。
我根据 balena-storage 制作了一个 mount.sh 文件。当我通过我正在部署的 balena.io 仪表板(在其他地方可能相同)和手动 运行 脚本登录到容器时,它会起作用。当容器启动时 运行s 脚本(一个 运行s 脚本的脚本)时,它会挂起未填充的变量。我认为这是权限问题或脚本 运行ning 脚本问题。我不确定如何继续读取 USB 设备变量。
mount.sh:
# Automatically mount a USB drive by specified volume name.
# Note: make sure to have USB_VOLUME_NAME set in env vars.
# Thanks: https://github.com/balena-io-playground/balena-storage
echo "Checking for USB_VOLUME_NAME..."
echo "A"
if [[ -z $USB_VOLUME_NAME ]]; then
echo "Make sure to set environment variable USB_VOLUME_NAME in order to find a connected USB drive by that label and connect to it. Exiting..." >> /usr/src/app/mount.log
exit 1
fi
echo "B"
# Get device by label env var set in balena.io dashboard device env vars
USB_DEVICE=$(blkid -L $USB_VOLUME_NAME)
if [[ -z $USB_DEVICE ]]; then
echo "Invalid USB_DEVICE name: $USB_DEVICE" >> /usr/src/app/mount.log
exit 1
fi
echo $USB_DEVICE
echo "C"
# Get extra device info
ID_FS_TYPE=${ID_FS_TYPE:=$(/bin/udevadm info -n $USB_DEVICE | /usr/bin/awk -F "=" '/ID_FS_TYPE/{ print }')}
ID_FS_UUID_ENC=${ID_FS_UUID_ENC:=$(/bin/udevadm info -n $USB_DEVICE | /usr/bin/awk -F "=" '/ID_FS_UUID_ENC/{ print }')}
ID_FS_LABEL_ENC=${ID_FS_LABEL_ENC:=$(/bin/udevadm info -n $USB_DEVICE | /usr/bin/awk -F "=" '/ID_FS_LABEL_ENC/{ print }')}
MOUNT_POINT=/mnt/$USB_VOLUME_NAME
echo $ID_FS_TYPE
echo $ID_FS_UUID_ENC
echo $ID_FS_LABEL_ENC
echo $MOUNT_POINT
echo "D"
# Bail if file system is not supported by the kernel
if ! /bin/grep -qw $ID_FS_TYPE /proc/filesystems; then
echo "File system not supported: $ID_FS_TYPE" >> /usr/src/app/mount.log
exit 1
fi
echo "E"
# Mount device
if /bin/findmnt -rno SOURCE,TARGET $USB_DEVICE >/dev/null; then
echo "Device $USB_DEVICE is already mounted!" >> /usr/src/mount.log
else
echo "Mounting - Source: $USB_DEVICE - Destination: $MOUNT_POINT" >> /usr/src/app/mount.log
/bin/mkdir -p $MOUNT_POINT
/bin/mount -t $ID_FS_TYPE -o rw $USB_DEVICE $MOUNT_POINT
fi
echo "F"
当容器 运行 执行脚本时,它卡在“D”之后,ID_FS_TYPE、ID_FS_UUID_ENC 和 ID_FS_LABEL_ENC 为空(这是一个很好的理由挂)。
输出:
Checking for USB_VOLUME_NAME...
A
B
/dev/sda1
C
/mnt/MYDRIVE
D
我的dockerfile.template:
FROM balenalib/%%BALENA_MACHINE_NAME%%-node
# Enable udev for detection of dynamically plugged devices
ENV UDEV=on
COPY udev/usb.rules /etc/udev/rules.d/usb.rules
# Install dependencies
RUN install_packages util-linux
WORKDIR /usr/src/app
# Move scripts used for mounting USB
COPY scripts scripts
RUN chmod +x scripts/*
# server.js will run when container starts up on the device
CMD ["/bin/bash", "/usr/src/app/scripts/start.sh"]
start.sh:
echo "Mounting USB drive..."
cd /usr/src/app/scripts
/bin/bash mount.sh
# It won't get this far while the script above hangs.
echo "Starting server..."
cd /usr/src/app
/usr/local/bin/yarn run serve
我可以确认当 运行手动从容器中运行时一切正常:
cd /usr/src/app/scripts
/bin/bash mount.sh
输出:
Checking for USB_VOLUME_NAME...
A
B
/dev/sda1
C
vfat
BE23-31BA
MYDRIVE
/mnt/MYDRIVE
D
E
F
(and the drive mounted)
如何解析空变量?
总是引用每个shell你使用的变量。 (除非您完全确定自己在做什么,以及如果变量值为空或包含 spaces 时您期望发生什么。)
不引用,当你
/bin/grep -qw $ID_FS_TYPE /proc/filesystems
和 $ID_FS_TYPE
是空的,这个词只是从命令行中省略了,所以你得到
/bin/grep -qw /proc/filesystems
将 /proc/filesystems
用作正则表达式,并尝试通过其标准输入进行 grep;这会导致您看到明显的挂起。
如果你引用它:
/bin/grep -qw "$ID_FS_TYPE" /proc/filesystems
它将获得一个空字符串作为正则表达式参数和一个文件名作为输入参数,这将成功(但不会挂起)。
出于类似的原因,如果 $USB_VOLUME_NAME
未设置,我希望您会收到 shell 语法错误,并且如果该变量名称具有 [=36],则整个脚本将表现得很奇怪=]在里面。