为何C++调用获取Ubuntu控制台空闲行的Shell脚本失效?
问题原因与解决方案
这个问题其实很好理解——你单独运行脚本时没问题,但用C++的system()调用就报错,核心原因是**system()默认使用的是/bin/sh而不是/bin/bash**,而sh的read命令并不支持-s这个选项,所以才会抛出Illegal option -s的错误。
单独运行脚本时,因为你在开头写了#!/bin/bash,系统会自动用bash来解释执行脚本;但system()函数会把你传入的字符串直接交给sh处理,sh不认read -s,自然就出错了。
那怎么解决呢?很简单,我们只需要让system()调用bash来执行这段脚本内容就行,有两种常见方式:
方式一:用bash -c包裹脚本内容
直接在脚本字符串前加上bash -c,让sh去启动bash来执行你的命令,这样就能用上bash特有的参数了。修改后的代码如下:
#include <cstdlib> using namespace std; #define SCRIPTGETNEXTLINE "bash -c 'echo -en \"\\E[6n\"; read -sdR CURPOS; CURPOS=${CURPOS#*[}; CURPOS=$(echo $CURPOS | cut -d \";\" -f 1); echo $CURPOS'" int main (){ system(SCRIPTGETNEXTLINE); return 0; }
这里把原本的多行脚本合并成了单行(用分号分隔命令),同时用单引号把整个脚本内容包裹起来,交给bash -c执行,这样就完全避开了sh的限制。
方式二:将脚本保存为文件再调用
如果你的脚本逻辑比较复杂,也可以把这段bash代码保存成一个单独的.sh文件(比如get_cursor_line.sh),然后在C++里用system("./get_cursor_line.sh")来调用,这样脚本开头的#!/bin/bash就会生效,同样能正常执行。
比如脚本文件内容:
#!/bin/bash echo -en "\E[6n" read -sdR CURPOS CURPOS=${CURPOS#*[} CURPOS=$(echo $CURPOS | cut -d ';' -f 1) echo $CURPOS
然后C++代码:
#include <cstdlib> using namespace std; int main (){ system("./get_cursor_line.sh"); return 0; }
记得给脚本加执行权限:chmod +x get_cursor_line.sh。
两种方式都能解决你的问题,看你更倾向于哪种写法啦~
内容的提问来源于stack exchange,提问作者wellar
相关产品推荐
相关产品推荐

