我有一台生成数据的设备,以及一个读取该设备内容的应用程序。我认为设置可以像这样举例说明:
设备 -->echo "ABC" >> /dev/mydevice
应用程序-->cat /dev/mydevice
应用程序输出:“ABC”
有没有办法可以强制应用程序在读取时获取不同的数据源/dev/mydevice
,考虑到我无法修改(写入/移动)/dev/mydevice
也无法更改应用程序读取的路径。
我需要这样的东西:
设备 -->echo "ABC" >> /dev/mydevice
我 -->echo "123" >> myinput.txt
我 --> 强制重定向/dev/mydevice
至myinput.txt
应用程序-->cat /dev/mydevice
应用程序输出:“123”
答案1
你可以试试普罗特(顺便说一下,你可能想要构建它的 git master)。
虽然它并不完全是“将(仅)读取一个文件重定向到另一个文件而不以任何方式更改该文件”,但它允许您创建一个环境,其中对文件(或实际上是路径)的所有访问都是在后台对另一个文件进行的:
[tom@archlinux ~]$ file /dev/zero /dev/urandom
/dev/zero: character special (1/5)
/dev/urandom: character special (1/9)
[tom@archlinux ~]$ proot -b /:/ -b /dev/urandom:/dev/zero
[tom@archlinux ~]$ file /dev/zero /dev/urandom
/dev/zero: character special (1/9)
/dev/urandom: character special (1/9)
[tom@archlinux ~]$ hexdump -C -n 16 /dev/zero
00000000 18 d1 ee 6f a8 9e 1e ac 99 60 db 79 79 e0 d9 f5 |...o.....`.yy...|
00000010
[tom@archlinux ~]$ hexdump -C -n 16 /dev/zero
00000000 03 60 15 53 f7 e3 15 43 05 7e ef 8e 68 8b 6b 49 |.`.S...C.~..h.kI|
00000010
[tom@archlinux ~]$ logout
[tom@archlinux ~]$ hexdump -C -n 16 /dev/zero
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000010
[tom@archlinux ~]$
[tom@archlinux ~]$ dd if=/dev/urandom bs=16 count=1 > sdc
1+0 records in
1+0 records out
16 bytes copied, 9.8566e-05 s, 162 kB/s
[tom@archlinux ~]$ file /home/tom/sdc
/home/tom/sdc: data
[tom@archlinux ~]$ hexdump -C /home/tom/sdc
00000000 6f 05 42 ee 9f 5d 3a 5d b4 27 d2 02 40 e4 ff d0 |o.B..]:].'..@...|
00000010
[tom@archlinux ~]$ proot -b /:/ -b /home/tom/sdc:/dev/sdc
[tom@archlinux ~]$ file /dev/sdc
/dev/sdc: data
[tom@archlinux ~]$ hexdump -C /dev/sdc
00000000 6f 05 42 ee 9f 5d 3a 5d b4 27 d2 02 40 e4 ff d0 |o.B..]:].'..@...|
00000010
[tom@archlinux ~]$ dd if=/dev/urandom bs=16 count=1 >> /dev/sdc
1+0 records in
1+0 records out
16 bytes copied, 0.000101888 s, 157 kB/s
[tom@archlinux ~]$ logout
[tom@archlinux ~]$ hexdump -C /home/tom/sdc
00000000 6f 05 42 ee 9f 5d 3a 5d b4 27 d2 02 40 e4 ff d0 |o.B..]:].'..@...|
00000010 5a c8 af 48 59 1c de 00 ba ff 88 a2 82 b4 bb 5c |Z..HY..........\|
00000020
[tom@archlinux ~]$ file /dev/sdc
/dev/sdc: cannot open `/dev/sdc' (No such file or directory)
[tom@archlinux ~]$
答案2
您可以在 上绑定挂载其他内容/dev/mydevice
。如果您先取消共享挂载命名空间,则系统的其余部分将不受影响。得益于-r
选项首先,您不需要是 root 身份。
unshare -r -m # run a shell in a new mount namespace
# Now you _appear_ to be root _locally_ (e.g. your files will appear root's),
# but to the outside of the shell you're the original user.
mount --bind myinput.txt /dev/mydevice
your_application -with --options and operands
exit # exit the shell, and hence the mount namespace
非交互式版本:
unshare -r -m sh << EOF
mount --bind myinput.txt /dev/mydevice
exec your_application -with --options and operands
EOF
笔记:
exec
因为保留没有意义sh
;- 如果您需要
your_application
以另一个用户身份运行,即使用sudo
,那么unshare
使用运行sudo
。
如果你得到unshare failed: Operation not permitted
(特别是在 Debian 中),那么看看这:
事实证明,Debian 内核默认禁止非特权用户取消共享用户命名空间。可以使用以下方法解决这个问题:
sudo su -c 'echo 1 > /proc/sys/kernel/unprivileged_userns_clone'
(原始命令中有拼写错误。上述引用已修复。)
sudo
另一种方法是像这样使用:
sudo unshare -m sh << 'EOF'
mount --bind myinput.txt /dev/mydevice
exec sudo -u "$SUDO_USER" your_application -with --options and operands
EOF
无论哪种方式你都有可能需要sudo
处理unshare failed: Operation not permitted
。
概念证明不依赖于或myinput.txt
,因此很有可能它开箱即用:/dev/mydevice
your_application
unshare -r -m sh << EOF
mount --bind /etc/fstab /dev/null
exec cat /dev/null
EOF