是否可以将读取重定向到 Linux 中的文件?

是否可以将读取重定向到 Linux 中的文件?

我有一台生成数据的设备,以及一个读取该设备内容的应用程序。我认为设置可以像这样举例说明:

设备 -->echo "ABC" >> /dev/mydevice

应用程序-->cat /dev/mydevice

应用程序输出:“ABC”

有没有办法可以强制应用程序在读取时获取不同的数据源/dev/mydevice,考虑到我无法修改(写入/移动)/dev/mydevice也无法更改应用程序读取的路径。

我需要这样的东西:

设备 -->echo "ABC" >> /dev/mydevice

我 -->echo "123" >> myinput.txt

我 --> 强制重定向/dev/mydevicemyinput.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/mydeviceyour_application

unshare -r -m sh << EOF
mount --bind /etc/fstab /dev/null
exec cat /dev/null
EOF

相关内容