首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从bash脚本中的Docker容器中运行的脚本获取USB设备信息?

如何从bash脚本中的Docker容器中运行的脚本获取USB设备信息?
EN

Stack Overflow用户
提问于 2020-07-22 21:22:34
回答 1查看 502关注 0票数 0

我制作了一个受巴莱纳-储存启发的巴莱纳-储存文件。当我通过我正在部署的balena.io仪表板登录到容器(可能在其他地方相同)并手动运行脚本时,它就可以工作了。当容器在启动时运行脚本(运行脚本的脚本)时,它会挂起未填充的变量。我认为这是一个权限问题或脚本运行脚本的事情。我不知道如何继续读取USB设备变量。

mount.sh:

代码语言:javascript
复制
# 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 $2 }')}
ID_FS_UUID_ENC=${ID_FS_UUID_ENC:=$(/bin/udevadm info -n $USB_DEVICE | /usr/bin/awk -F "=" '/ID_FS_UUID_ENC/{ print $2 }')}
ID_FS_LABEL_ENC=${ID_FS_LABEL_ENC:=$(/bin/udevadm info -n $USB_DEVICE | /usr/bin/awk -F "=" '/ID_FS_LABEL_ENC/{ print $2 }')}

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都是空的(这是挂起的一个很好的理由)。

产出:

代码语言:javascript
复制
Checking for USB_VOLUME_NAME...
A
B
/dev/sda1
C



/mnt/MYDRIVE
D

我的dockerfile.template:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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

我可以确认,在从容器中手动运行时,所有操作都正常:

代码语言:javascript
复制
cd /usr/src/app/scripts
/bin/bash mount.sh

输出:

代码语言:javascript
复制
Checking for USB_VOLUME_NAME...
A
B
/dev/sda1
C
vfat
BE23-31BA
MYDRIVE
/mnt/MYDRIVE
D
E
F
(and the drive mounted)

如何解析空变量?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-22 21:28:53

始终引用您使用的每个shell变量。(除非您完全确定您在做什么,以及如果变量值为空或包含空格,则会发生什么。)

没有引用,当你

代码语言:javascript
复制
/bin/grep -qw $ID_FS_TYPE /proc/filesystems

$ID_FS_TYPE是空的,这个单词在命令行中被省略了,所以

代码语言:javascript
复制
/bin/grep -qw /proc/filesystems

它使用/proc/filesystems作为regexp,并尝试通过stdin实现grep;这将导致明显的挂起。

如果你引用它:

代码语言:javascript
复制
/bin/grep -qw "$ID_FS_TYPE" /proc/filesystems

它将获得一个空字符串作为regexp参数,一个文件名作为输入参数,这将很小地成功(但不会挂起)。

出于类似的原因,如果$USB_VOLUME_NAME未设置,我希望您会得到一个shell语法错误,如果变量名中有一个空格,整个脚本就会很奇怪。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63043409

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档