2014-08-27 54 views
0

我使用Ubuntu。我试图用通配符来使用system()函数,并且每次运行该函数时,都需要*作为文字。我在系统中使用的命令是echo。它看起来像这样。如何获得系统()使用通配符

system("echo cape-bone-iio > /sys/devices/bone_capmgr.*/slots) 

我试过对它和其他许多东西进行尝试,但我无法使这个通配符工作。它返回一个错误:

Sh: 1: cannot create /sys/devices/bone_capemgr.*/slots 

它,当我通过终端,但没有从程序上运行它的工作原理

我有一种变通方法,它只是通过数从0到99个周期,但它占用了更多的资源比我想。我知道使用系统命令并不安全,但我严格使用beaglebone系统。

+1

你确定它可以在终端上工作吗?看起来像是一个“模棱两可的重定向”给我。 – 2014-08-27 21:37:17

+0

是的。没有错误,当我检查文件,它是所有的 – cmacia06 2014-08-27 21:38:17

+1

你去这个错误,你应该直接写入'slots'文件 – vanjoe 2014-08-27 21:38:33

回答

3

/sys/devices/bone_capmgr.*/slots通配是由shell中运行你的echo之前扩大。阅读glob(7)。如果匹配两个文件(例如,具有*是要么27)您的命令被扩展为:

echo cape-bone-iio > \ 
    /sys/devices/bone_capmgr.2/slots /sys/devices/bone_capmgr.7/slots 

,你看到那么它是无感。 (但它才有意义,如果*扩大到一件事像4)。如果没有文件匹配globbing模式,你的shell可能会在里面创建一个*的文件名(这会触发cannot create /sys/devices/bone_capemgr.*/slots消息)。

您可能会遇到也许

for f in /sys/devices/bone_capmgr.*/slots ; do \ 
    echo cape-bone-iio > $f ; \ 
done 

但我不认为经过这么长的字符串system始终是一个好主意。你可以做的for循环在你的C程序(例如使用opendir(3) + readdir(3)/sys/devices/ ...),那么你甚至不需要任何system(使用readdir只是一些fopen + fprintf +在循环fclose ...)。您也可以使用glob(3)wordexp(3)

如果没有/sys/devices/bone_capmgr.*/slots文件存在,例如,您可能需要处理这种情况。因为某些硬件缺失或未连接。

BTW,由system(3)调用的外壳将扫描的目录,如readdir(或globwordexp)做的,所以手工编写这个循环避免分叉壳应稍快运行。

您也可以使用nftw(3),但我认为这对您的需求太笼统了。它会递归扫描文件树,如find(1)命令所做的那样。

你也可以使用snprintf生成一个文件名,在for (ix=0; ix<100; x++)循环使用access(2)

最后测试它的存在,你也许对这查询这些设备的存在直通/proc/(见proc(5)更多,如果它揭露了一些关于你的硬件的东西)。 udev(7)也可能是相关的。

BTW尝试strace(1)外壳在终端(或简称strace /bin/sh -c "echo cape-bone-iio > /sys/devices/bone_capmgr.*/slots")解释你的echo命令找出你的外壳使用的syscalls(2)

shell没有任何功能,你无法使用纯系统调用。

+0

谢谢你的回复!问题是我无法直接从程序写入文件。只有一个具有该名称的文件,但每次启动都会更改数字。 – cmacia06 2014-08-27 21:52:54

+3

但你可以'readdir'包含该文件的目录来找到该文件,因此编号... – 2014-08-27 21:53:43

+0

我想添加最好的解决方案是在C程序中使用glob。这使得它变得更容易。 – cmacia06 2014-10-08 19:48:51

-1

首先,我必须说,你应该直接写入文件,而不是产生一个过程来为你做。

说了这么多,你可以做你通过 system("sh -c 'echo cape-bone-iio > /sys/devices/bone_capmgr.*/slots'")

+0

无用,因为根据定义'system'是分叉'/ bin/sh -c'! – 2014-08-27 22:04:17

+0

真的吗?这似乎愚蠢。难怪它从未被使用过。 – vanjoe 2014-08-27 22:32:40

1

问什么。如果你坚持使用system呼叫,则另一个备选方案是find命令:

system("find /sys/devices/ -type d -name 'bone_capmgr.*'" 
     " -exec sh -c 'echo cap-bone-iio > {}/slots' \;" ); 

这则防止注释中提到的模糊重定向错误应该有多个目录匹配全局模式bone_capmgr.*

但是,我会建议采取由Basile Starynkevitch提供的建议。

相关问题