linux C程序中获取shell脚本输出

2023-11-18

分类: linux C开发 2008-06-16 22:44  820人阅读  评论(0)  收藏  举报

目录(?)[+]

linux C程序中获取shell脚本输出

 

本文使用docbook书写,您可以在这里获得xml文件  

Abstract

本文描述了从Linux程序中执行shell(程序、脚本)并获得输出结果的方法。


1. 前言

Unix界有一句名言:“一行shell脚本胜过万行C程序”,虽然这句话有些夸张,但不可否认的是,借助脚本确实能够极大的简化一些编程工作。比如实现一个ping程序来测试网络的连通性,实现ping函数需要写上200~300行代码,为什么不能直接调用系统的ping命令呢?通常在程序中通过system函数来调用shell命令。但是,system函数仅返回命令是否执行成功,而我们可能需要获得shell命令在控制台上输出的结果。例如,执行外部命令ping后,如果执行失败,我们希望得到ping的返回信息。

2. 使用临时文件

首先想到的方法就是将命令输出重定向到一个临时文件,在我们的应用程序中读取这个临时文件,获得外部命令执行结果,代码如下所示:

    #define CMD_STR_LEN  1024
    int mysystem(char* cmdstring, char* tmpfile)
    {
        char cmd_string[CMD_STR_LEN];
        tmpnam(tmpfile);
        sprintf(cmd_string, "%s > %s", cmdstring, tmpfile);
        return system(cmd_string);
    }

这种使用使用了临时文件作为应用程序和外部命令之间的联系桥梁,在应用程序中需要读取文件,然后再删除该临时文件,比较繁琐,优点是实现简单,容易理解。有没有不借助临时文件的方法呢?

3. 使用匿名管道

在<<UNIX环境高级编程>>一书中给出了一种通过匿名管道方式将程序结果输出到分页程序的例子,因此想到,我们也可以通过管道来将外部命令的结果同应用程序连接起来。方法就是fork一个子进程,并创建一个匿名管道,在子进程中执行shell命令,并将其标准输出dup到匿名管道的输入端,父进程从管道中读取,即可获得shell命令的输出,代码如下:

  /**
   * 增强的system函数,能够返回system调用的输出
   *
   * @param[in] cmdstring 调用外部程序或脚本的命令串
   * @param[out] buf 返回外部命令的结果的缓冲区
   * @param[in] len 缓冲区buf的长度
   *
   * @return 0: 成功; -1: 失败 
   */
  int mysystem(char* cmdstring, char* buf, int len)
  {
      int   fd[2];
      pid_t pid;
      int   n, count; 
      memset(buf, 0, len);
      if (pipe(fd) < 0)
          return -1;
      if ((pid = fork()) < 0)
          return -1;
      else if (pid > 0)     /* parent process */
      {
          close(fd[1]);     /* close write end */
          count = 0;
          while ((n = read(fd[0], buf + count, len)) > 0 && count > len)
              count += n;
          close(fd[0]);
          if (waitpid(pid, NULL, 0) > 0)
              return -1;
      }
      else                  /* child process */
      {
          close(fd[0]);     /* close read end */
          if (fd[1] != STDOUT_FILENO)
          {
              if (dup2(fd[1], STDOUT_FILENO) != STDOUT_FILENO)
              {
                  return -1;
              }
              close(fd[1]);
          } 
          if (execl("/bin/sh", "sh", "-c", cmdstring, (char*)0) == -1)
              return -1;
      } 
      return 0;
  }
  

4. 使用popen

在学习unix编程的过程中,发现系统还提供了一个popen函数,可以非常简单的处理调用shell,其函数原型如下:

FILE *popen(const char *command, const char *type);

该函数的作用是创建一个管道,fork一个进程,然后执行shell,而shell的输出可以采用读取文件的方式获得。采用这种方法,既避免了创建临时文件,又不受输出字符数的限制,推荐使用。

5. 小结

有统计数据表明,代码的缺陷率是一定的,与所使用的语言无关。Linux提供了很多的实用工具和脚本,在程序中调用工具和脚本,无疑可以简化程序,从而降低代码的缺陷数目。Linux shell脚本也是一个强大的工具,我们可以根据需要编制脚本,然后在程序中调用自定义脚本。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux C程序中获取shell脚本输出 的相关文章

  • Linux 从设备本身运行的脚本卸载设备

    我在路径中安装了一个 iso 映像 mnt iso 在这个 iso 中我有一个安装脚本 install sh 我从 iso 运行安装脚本 最后脚本询问用户是否要卸载 iso 本身 如果用户按 y 脚本将执行以下代码 cd umount mn
  • 在 bash 脚本中设置变量[重复]

    这个问题在这里已经有答案了 test sh 包含 A 1 B 2 我将 test sh 设置为 chmod 777 我用两个参数启动脚本 test sh first last 然后我通过输入以下内容对其进行了测试 echo FirstVar
  • shell 脚本中的 Telnet

    如何在 shell 脚本中运行 telnet 并在远程服务器上执行命令 出于安全原因 我没有在我的Solaris 机器上安装expect 我也没有perlnet telnet模块已安装 那么如果不使用expect和perl我该怎么办呢 我尝
  • “bash -c 命令参数”末尾的参数的目的是什么?

    From man bash If the c option is present then commands are read from the first non option argument command string If the
  • 如何在bash中使用kill SIGUSR2?

    我在linux中使用iptraf来监控网络流量 shell命令是 让iptraf在后台运行 iptraf s eth0 f B L traffic dat 如果我想得到结果 我必须先停止 iptraf 所以我使用 shell 命令 kill
  • python等待shell命令完成

    我正在运行脚本来解压缩一些文件 然后删除 rar 文件 我通过 shell 运行命令来完成此操作 我尝试了几种不同的方法来让脚本等待文件解压完成 但它仍然继续并在文件使用完成之前删除文件 我已经尝试过下面的代码 这是行不通的 我试图看看是否
  • 何时用引号将 shell 变量括起来?

    我应该或不应该在 shell 脚本中用引号括住变量吗 例如 下列说法正确的是 xdg open URL eq 2 or xdg open URL eq 2 如果是这样 为什么 一般规则 如果它可以为空或包含空格 或实际上任何空格 或特殊字符
  • Python 脚本:每次打印新行到 shell,而不是更新现有行

    说到Python 我是个菜鸟 我有一个 python 脚本 它给我这样的输出 last ZVZX W3vo9I Downloading video webpage last ZVZX W3vo9I Extracting video info
  • 为什么 fork 炸弹没有使 android 崩溃?

    这是最简单的叉子炸弹 我在许多 Linux 发行版上执行了它 但它们都崩溃了 但是当我在 android 终端中执行此操作时 即使授予后也没有效果超级用户权限 有什么解释为什么它没有使 Android 系统崩溃吗 一句话 ulimit Li
  • 如何从 LaTeX 执行 shell 脚本?

    我正在尝试在 LaTeX 中执行以下操作 documentclass article begin document execute usr local bin my shell script sh end document 想法是执行 us
  • 是否有 ADB 命令来检查媒体是否正在播放

    我想使用 ADB 命令检查根植于终端的外部设备中是否正在播放音频 视频 我无法找到任何 ADB 命令 如果有 我尝试过 adb shell dumpsys media player 我想要一个命令来指定视频是否正在运行 您可以使用以下命令查
  • 执行“minikube start”命令时出现问题

    malik malik minikube start minikube v1 12 0 on Ubuntu 18 04 Using the docker driver based on existing profile Starting c
  • 添加文件时运行 shell 命令

    我的 Linux 机器上有一个名为 images 的文件夹 该文件夹连接到一个网站 该网站的管理员可以向该网站添加图片 但是 当添加图片时 我想要一个命令来运行调整目录中所有图片的大小 简而言之 我想知道当新文件添加到特定位置时如何使服务器
  • 如何正确使用fork、exec、wait

    我正在编写的 shell 需要执行用户提供给它的程序 这是我的程序的非常简短的简化版本 int main pid t pid getpid this is the parents pid char user input NULL size
  • 使用 shell 脚本将行附加到 /etc/hosts 文件

    我有一个新的 Ubuntu 12 04 VPS 我正在尝试编写一个安装脚本来完成整个 LAMP 安装 我遇到问题的地方是在 etc hosts文件 我当前的主机文件如下所示 127 0 0 1 localhost Venus The fol
  • Bash - 在与当前终端分开的另一个终端中启动命令的新实例

    我有一个简单的 bash 脚本 test sh 设置如下 bin bash args if args 0 check capture then watch n 1 ls lag home user capture0 watch n 1 ls
  • 使用 python 脚本更改 shell 中的工作目录

    我想实现一个用户态命令 它将采用其参数之一 路径 并将目录更改为该目录 程序完成后 我希望 shell 位于该目录中 所以我想实施cd命令 但需要外部程序 可以在 python 脚本中完成还是我必须编写 bash 包装器 Example t
  • 如何在 *nix 中登录时运行脚本?

    我知道我曾经知道如何做到这一点 但是 如何在 unix 中登录时运行脚本 bash 可以 From 维基百科 Bash http en wikipedia org wiki Bash 28Unix shell 29 当 Bash 启动时 它
  • Jenkins:如何在 Windows 从机中执行 shell 脚本

    我有一个 Windows 从机 安装了 bash 我正在尝试在其上运行 shell 脚本作为预构建步骤 关于我如何做到这一点有什么想法吗 您需要使用脚本作为参数来运行 bash bash yourscript
  • 测试 bash shell 脚本[重复]

    这个问题在这里已经有答案了 有人可以解释一下如何测试 bash shell 脚本吗 例如 我有一个 sh 文件 其中包含此代码 bin sh for file in txt do mv file basename file txt doc

随机推荐

  • 时序预测

    作者简介 热爱科研的Matlab仿真开发者 修心和技术同步精进 matlab项目合作可私信 个人主页 Matlab科研工作室 个人信条 格物致知 内容介绍 时间序列流量的预测问题是近年来机器学习的一个热点问题 通过改变长短期记忆网络 LST
  • 如何查看mysql 的用户名和密码

    如何查看mysql 的用户名和密码 首先 这个是内部查看 意思就是登录了查看的 windo r 输入cmd 2 切换到 mysql bin 目录 3 登录 4 查看命令 select from mysql user
  • Ubuntu 16.04 Java8 安装

    添加ppa sudo add apt repository ppa webupd8team java sudo apt get update 安装oracle java installer sudo apt get install orac
  • Java class 中public、protected 、friendly、private的区别

    Java class 中public protected friendly private的区别 1 类 class 可见性修饰符 public 在所有类中可见 在其他包中可以用import导入 缺省 就是没有修饰符 在同一个包中的类中可见
  • CSS设置视频背景透明

    background 000 mix blend mode screen
  • git无法连接远程仓库(GitHub)

    问题描述 某一天 开开心心的写完了一篇博客 在向GitHub推送的时候突然报错了 乍一看 报错了 顿时 通过查阅资料尝试了几种方法之后解决了 在这做个记录 解决方法 首先需要检查一下SSH是否能够连接成功 输入以下命令 ssh T git
  • 已创建了一个包含学生学号、身高、性别的学生身高信息表并输出到屏幕,学生信息从records.txt文件读取。 编写一个函数 void reverse(Seqlist *lp); 功能是对已建立的学生身

    已创建了一个包含学生学号 身高 性别的学生身高信息表并输出到屏幕 学生信息从records txt文件读取 结构体数组版本 1 30 编写一个函数 void reverse Seqlist lp 功能是对已建立的学生身高信息表进行倒置 结果
  • 实验七、文件系统

    1 为 Ext4 文件系统添加扩展属性 扩展属性分为以下四种 1 扩展的安全属性 security 安全属性名称空间被内核用于安全模块 例如SELinux 对安全属性的读和写权限依赖于策略的设定 这策略是由安全模块载入的 如果没有载入安全模
  • 【记录】批处理文件提取 (2020.8.26)

    写在前面 文件的批处理可以帮我们节约大量的时间及精力 最近网上冲浪的时候找到一些不错的资源 赶紧保存 但是下载下来后发现资源实在是太套娃了 虽说是全集不假 但是一层套着一层 让人心累 想到批处理的方法 能不能用脚本帮我把文件都提取出来呢 说
  • 持续自适应信任(CAT)-企业零信任最佳范式|身份云研究院

    零信任安全治理理念不再是陌生的话题 随着社会面临更复杂的信息安全风险 不断变化的网络环境使得基于边界的安全架构不再具备抵御内外部安全威胁的能力 传统的以网络中心化的安全体系架构也逐步过渡到以身份为中心的网络访问控制理念 基于零信任理念衍生的
  • windows下以指定用户访问SMB服务器进行读写

    一 概述 最近遇到一个问题 linux 的 smb服务器开启匿名访问 windows访问linux文件夹不需要用户名密码就可以进去使用 但是存在一个问题 ssh连接到linux 后修改的文件 在windows已smb方式下打开某个文件修改
  • 【文献翻译】信息安全管理自动化的可能性 - Automation possibilities in information security management

    摘要 ISO 27001中定义的信息安全管理涉及建立 实施 操作 监控 审查 维护和改进信息安全管理系统 本文分析了信息安全管理自动化的可能性 该分析考虑了使用 i 风险管理中的安全本体 ii 用于某些安全控制自动运行的硬件和软件系统 以及
  • JVM3-类文件结构

    六 类文件结构 计算机到目前为止 都只能识别0和1 所以我们写的程序都需要被编译器翻译成0和1的二进制格式才能被计算机执行 很多程序语言选择了与操作系统和机器指令集无关的 平台中立的格式作为程序编译后的格式 而不再需要像最初那样把程序编译成
  • PMP课程笔记:第4章 项目整合管理

    目录 预测型生命周期 0 项目整合管理的基本概念 1 项目整合管理 2 整合的发展趋势 3 项目管理过程三从四德 4 项目整合管理实现过程 重要 1 制定项目章程 1 1 制定项目章程 输入 1 2 制定项目章程 输出 1 3 制定项目章程
  • 使用RPC对某者web端骑行数据进行爬取

    使用RPC技术hook web端JS 骑行app某者web端爬虫 2022 2 1 获取轨迹ID 通过更改年月 可以发现获取每个月轨迹ID 的方式 这个非常简单 只需要拷贝请求头headers就可以直接获取 2 获取轨迹详情 可以发现三个请
  • 主键和唯一索引

    主键和唯一索引 主键 主关键字 primary key 是表中的一个或多个字段 它的值用于唯一地标识表中的某一条记录 唯一索引 一种索引 不允许具有索引值相同的行 从而禁止重复的索引或键值 系统在创建该索引时检查是否有重复的键值 并在每次使
  • 【生信原理】初探芯片表达谱分析

    初探芯片表达谱分析 文章目录 初探芯片表达谱分析 实验目的 实验内容 实验题目 实验过程 数据的获取 解压与读取 数据预处理 背景纠正 标准化和探针信号汇总等 数据过滤 探针过滤 探针注释 添加基因注释信息 limma差异分析 差异表达基因
  • DM备份数据或者还原备份管道连接超时问题。

    问题 第一 必须以dmdba的用户执行 第二 启动DmAPService 服务 启动失败了 删掉管道文件再启动 启动成功 再执行就OK了
  • 【华为OD机试 2023 B卷

    在线OJ 已购买本专栏用户 请私信博主开通账号 在线刷题 运行出现 Runtime Error 0Aborted 请忽略 华为OD统一考试A卷 B卷 新题库说明 2023年5月份 华为官方已经将的 2022 0223Q 1 2 3 4 统一
  • linux C程序中获取shell脚本输出

    linux C程序中获取shell脚本输出 分类 linux C开发 2008 06 16 22 44 820人阅读 评论 0 收藏 举报 shell 脚本 linux c system cmd 目录 linux C程序中获取shell脚本