c语言在Linux中的使用
如何验证gcc正常使用,编译c以及运行
过程
要验证GCC(GNU Compiler Collection)是否正常使用,您可以按照以下步骤进行操作:
-
检查GCC是否安装:
打开终端或命令行界面,输入以下命令来检查GCC是否已安装:
gcc --version
如果GCC已正确安装,您将看到GCC的版本信息。如果没有安装,您会看到类似“command not found”的错误信息。
2. 编写一个简单的C程序:
创建一个名为hello.c
的文件,并输入以下代码:
#include <stdio.h> int main() { printf("Hello, World!\n"); return 0; }
保存并关闭文件。
3. 编译C程序:
在终端或命令行界面中,导航到包含hello.c
文件的目录,并输入以下命令来编译它:
gcc hello.c -o hello
此命令将使用GCC编译器将hello.c
文件编译为一个名为hello
的可执行文件。
4. 运行编译后的程序:
输入以下命令来运行编译后的程序:
./hello
如果一切正常,您将在终端或命令行界面中看到“Hello, World!”的输出。
通过以上步骤,您可以验证GCC是否正常工作。如果在编译或运行程序时遇到错误,请检查GCC的安装和配置,以及确保您的C代码没有语法错误。
过程执行,编译c以及演示
[root@vm-qa-mcw.xx.xx.com ares]# ls gcc-7.5.0 gcc-7.5.0-build gcc-7.5.0.tar.gz gccbak hello.c [root@vm-qa-mcw.xx.xx.com ares]# which gcc /usr/local/bin/gcc [root@vm-qa-mcw.xx.xx.com ares]# cat hello.c #include <stdio.h> int main() { printf("Hello, World!\n"); return 0; } [root@vm-qa-mcw.xx.xx.com ares]# [root@vm-qa-mcw.xx.xx.com ares]# [root@vm-qa-mcw.xx.xx.com ares]# ls gcc-7.5.0 gcc-7.5.0-build gcc-7.5.0.tar.gz gccbak hello.c [root@vm-qa-mcw.xx.xx.com ares]# which gcc /usr/local/bin/gcc [root@vm-qa-mcw.xx.xx.com ares]# gcc --version gcc (GCC) 7.5.0 Copyright (C) 2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. [root@vm-qa-mcw.xx.xx.com ares]# ls gcc-7.5.0 gcc-7.5.0-build gcc-7.5.0.tar.gz gccbak hello.c [root@vm-qa-mcw.xx.xx.com ares]# gcc hello.c -o hello [root@vm-qa-mcw.xx.xx.com ares]# ls gcc-7.5.0 gcc-7.5.0-build gcc-7.5.0.tar.gz gccbak hello hello.c [root@vm-qa-mcw.xx.xx.com ares]# ./hello Hello, World! [root@vm-qa-mcw.xx.xx.com ares]#
c调用shell脚本
在C++中调用Shell脚本,你可以使用system()
函数,它位于<cstdlib>
库中。这个函数可以执行一个shell命令,并等待它完成。下面是一个简单的例子:
#include <cstdlib> // for system() int main() { int result = system("./your_script.sh"); if (result == 0) { std::cout << "Shell script executed successfully." << std::endl; } else { std::cout << "Shell script execution failed." << std::endl; } return 0; }
在这个例子中,system("./your_script.sh")
会执行名为your_script.sh
的Shell脚本。system()
函数会返回命令的退出状态,通常,如果命令成功执行,返回0;否则返回非零值。
但是,需要注意的是,system()
函数有一些缺点。例如,它可能会引入安全漏洞(特别是当你执行的命令包含用户输入时),并且它无法捕获命令的标准输出或错误输出。如果你需要更精细的控制,你可能需要使用更复杂的库,如popen()
或fork()
和exec()
的组合。
另外,system()
函数在不同的操作系统和平台上可能会有不同的行为,因此如果你的代码需要在多个平台上运行,你需要特别小心。
最后,别忘了给你的Shell脚本添加执行权限。在Linux或Mac OS上,你可以使用chmod +x your_script.sh
命令来添加执行权限。
上面执行报错了
# gcc mcw.c -o mcw mcw.c:1:10: fatal error: cstdlib: No such file or directory #include <cstdlib> // for system() ^~~~~~~~~ compilation terminated.
下面用这个
在C语言中,调用Shell脚本通常涉及使用system()
函数,这个函数定义在<stdlib.h>
头文件中。system()
函数会启动一个子shell来执行指定的命令,并等待命令执行完成。下面是一个简单的例子:
#include <stdlib.h> // for system() #include <stdio.h> // for printf() int main() { int result = system("./your_script.sh"); if (result == 0) { printf("Shell script executed successfully.\n"); } else { printf("Shell script execution failed.\n"); } return 0; }
在这个例子中,system("./your_script.sh")
会调用名为your_script.sh
的Shell脚本。system()
函数返回命令的退出状态。如果命令成功执行,通常返回0;如果执行失败,返回非零值。
在使用system()
函数时,请确保以下几点:
-
Shell脚本的路径是正确的,并且脚本具有执行权限。在Unix-like系统(如Linux或macOS)上,你可以使用
chmod +x your_script.sh
来添加执行权限。 -
如果Shell脚本依赖于特定的环境变量或当前工作目录,你需要确保这些在调用脚本之前都已经正确设置。
-
system()
函数会启动一个新的shell进程来执行命令,这可能会带来性能开销。如果你需要频繁地调用Shell命令,或者需要更精细地控制输入/输出,你可能需要考虑使用更低级别的进程控制函数,如fork()
和exec()
系列函数。 -
使用
system()
时要特别小心安全问题,尤其是当命令字符串包含用户输入时。不正确的处理可能导致命令注入攻击。确保不要直接拼接用户输入到命令字符串中,或者使用安全的方法来转义或过滤用户输入。 -
system()
函数的行为可能依赖于特定的操作系统和shell环境,因此在跨平台开发中需要格外小心。
最后,记住在程序结束时检查system()
的返回值,以确定Shell脚本是否成功执行。这有助于你调试程序,并在必要时向用户报告错误。
[root@mcwtest ares]# ls gcc-7.5.0 gcc-7.5.0-build gcc-7.5.0.tar.gz gccbak hello hello.c mcw.c your_script.sh [root@mcwtest ares]# cat mcw.c #include <stdlib.h> // for system() #include <stdio.h> // for printf() int main() { int result = system("./your_script.sh"); if (result == 0) { printf("Shell script executed successfully.\n"); } else { printf("Shell script execution failed.\n"); } return 0; } [root@mcwtest ares]# cat your_script.sh echo "wo shi machangwei" [root@mcwtest ares]# gcc mcw.c -o mcw [root@mcwtest ares]# ls gcc-7.5.0 gcc-7.5.0-build gcc-7.5.0.tar.gz gccbak hello hello.c mcw mcw.c your_script.sh [root@mcwtest ares]# mcw bash: mcw: command not found [root@mcwtest ares]# ./mcw sh: ./your_script.sh: Permission denied Shell script execution failed. [root@mcwtest ares]# ls -lh your_script.sh -rw-r--r-- 1 root root 26 Apr 24 12:42 your_script.sh [root@mcwtest ares]# chmod u+x your_script.sh [root@mcwtest ares]# ./mcw wo shi machangwei Shell script executed successfully. [root@mcwtest ares]#
这样应该也可以调用其他脚本,只要是终端命令都可以。也可以其他程序调用c程序命令,这相当于程序命令,相当于终端命令了。里面应该也可以调用python
如果再研究下c怎么传递参数,然后将参数传给里面调用的脚本。这样就可以将我们的程序不暴露出来了,多了一层保护。比如zabbix,也不一定要调用python,shell采集机器的监控数据,也可以调用c脚本。
objdump,将上面gcc编译后的二进制文件,显示出汇编情况
objdump
是一个在 Linux 和其他类 Unix 系统上常用的程序,用于显示二进制文件的信息。它可以用来查看各种格式的目标文件的信息,如可执行文件、目标文件、共享库文件等。使用 objdump
,你可以查看二进制文件的汇编代码、符号表、重定位表以及其他相关信息。
以下是使用 objdump
显示二进制文件信息的一些基本用法和示例:
基本用法
objdump
的基本语法是:
objdump [options] file |
其中 file
是你要分析的二进制文件的路径。
查看汇编代码
如果你想查看二进制文件的汇编代码,可以使用 -d
或 --disassemble
选项。例如:
objdump -d binaryfile |
这个命令会显示 binaryfile
的反汇编结果,包括地址、机器码和汇编指令等信息。
查看符号表信息
使用 -t
或 --syms
选项,你可以查看二进制文件的符号表信息。例如:
objdump -t binaryfile |
这个命令会显示 binaryfile
的符号表,包括符号名、地址、大小和类型等信息。
其他常用选项
-f
或--file-headers
:显示文件的整体头部摘要信息。-h
或--section-headers
:显示目标文件中各个段的头部摘要信息。-I
或--info
:显示支持的目标文件格式和 CPU 架构。-j name
或--section=name
:显示指定段的信息。-m machine
或--architecture=machine
:指定反汇编目标文件时使用的架构。
这些选项可以帮助你更深入地了解二进制文件的结构和内容。通过组合这些选项,你可以定制 objdump
的输出以满足你的具体需求。
请注意,为了获得最佳的结果,你可能需要对汇编语言和你正在分析的二进制文件的上下文有一定的了解。此外,虽然 objdump
是一个强大的工具,但它可能无法提供关于二进制文件的所有信息,特别是当文件被加密、混淆或压缩时。
[root@mcwtest ares]# objdump -t mcw mcw: file format elf64-x86-64 SYMBOL TABLE: 0000000000400238 l d .interp 0000000000000000 .interp 0000000000400254 l d .note.ABI-tag 0000000000000000 .note.ABI-tag 0000000000400278 l d .hash 0000000000000000 .hash 00000000004002a0 l d .dynsym 0000000000000000 .dynsym 0000000000400318 l d .dynstr 0000000000000000 .dynstr 000000000040035c l d .gnu.version 0000000000000000 .gnu.version 0000000000400368 l d .gnu.version_r 0000000000000000 .gnu.version_r 0000000000400388 l d .rela.dyn 0000000000000000 .rela.dyn 00000000004003a0 l d .rela.plt 0000000000000000 .rela.plt 0000000000400400 l d .init 0000000000000000 .init 0000000000400420 l d .plt 0000000000000000 .plt 0000000000400470 l d .text 0000000000000000 .text 00000000004005f4 l d .fini 0000000000000000 .fini 0000000000400600 l d .rodata 0000000000000000 .rodata 0000000000400668 l d .eh_frame_hdr 0000000000000000 .eh_frame_hdr 00000000004006a0 l d .eh_frame 0000000000000000 .eh_frame 0000000000600e18 l d .init_array 0000000000000000 .init_array 0000000000600e20 l d .fini_array 0000000000000000 .fini_array 0000000000600e28 l d .dynamic 0000000000000000 .dynamic 0000000000600ff8 l d .got 0000000000000000 .got 0000000000601000 l d .got.plt 0000000000000000 .got.plt 0000000000601038 l d .data 0000000000000000 .data 0000000000601048 l d .bss 0000000000000000 .bss 0000000000000000 l d .comment 0000000000000000 .comment 0000000000000000 l df *ABS* 0000000000000000 crtstuff.c 00000000004004a0 l F .text 0000000000000000 deregister_tm_clones 00000000004004d0 l F .text 0000000000000000 register_tm_clones 0000000000400510 l F .text 0000000000000000 __do_global_dtors_aux 0000000000601048 l O .bss 0000000000000001 completed.6942 0000000000600e20 l O .fini_array 0000000000000000 __do_global_dtors_aux_fini_array_entry 0000000000400540 l F .text 0000000000000000 frame_dummy 0000000000600e18 l O .init_array 0000000000000000 __frame_dummy_init_array_entry 0000000000000000 l df *ABS* 0000000000000000 mcw.c 0000000000000000 l df *ABS* 0000000000000000 crtstuff.c 0000000000400790 l O .eh_frame 0000000000000000 __FRAME_END__ 0000000000000000 l df *ABS* 0000000000000000 0000000000600e20 l .init_array 0000000000000000 __init_array_end 0000000000600e28 l O .dynamic 0000000000000000 _DYNAMIC 0000000000600e18 l .init_array 0000000000000000 __init_array_start 0000000000400668 l .eh_frame_hdr 0000000000000000 __GNU_EH_FRAME_HDR 0000000000601000 l O .got.plt 0000000000000000 _GLOBAL_OFFSET_TABLE_ 00000000004005f0 g F .text 0000000000000002 __libc_csu_fini 0000000000601038 w .data 0000000000000000 data_start 0000000000000000 F *UND* 0000000000000000 puts@@GLIBC_2.2.5 0000000000601048 g .data 0000000000000000 _edata 00000000004005f4 g F .fini 0000000000000000 _fini 0000000000000000 F *UND* 0000000000000000 system@@GLIBC_2.2.5 0000000000000000 F *UND* 0000000000000000 __libc_start_main@@GLIBC_2.2.5 0000000000601038 g .data 0000000000000000 __data_start 0000000000000000 w *UND* 0000000000000000 __gmon_start__ 0000000000601040 g O .data 0000000000000000 .hidden __dso_handle 0000000000400600 g O .rodata 0000000000000004 _IO_stdin_used 0000000000400580 g F .text 0000000000000065 __libc_csu_init 0000000000601050 g .bss 0000000000000000 _end 0000000000400470 g F .text 0000000000000000 _start 0000000000601048 g .bss 0000000000000000 __bss_start 0000000000400547 g F .text 0000000000000038 main 0000000000601048 g O .data 0000000000000000 .hidden __TMC_END__ 0000000000400400 g F .init 0000000000000000 _init [root@mcwtest ares]# ls gcc-7.5.0 gcc-7.5.0-build gcc-7.5.0.tar.gz gccbak hello hello.c mcw mcw.c your_script.sh [root@mcwtest ares]# objdump -d mcw mcw: file format elf64-x86-64 Disassembly of section .init: 0000000000400400 <_init>: 400400: 48 83 ec 08 sub $0x8,%rsp 400404: 48 8b 05 ed 0b 20 00 mov 0x200bed(%rip),%rax # 600ff8 <__gmon_start__> 40040b: 48 85 c0 test %rax,%rax 40040e: 74 05 je 400415 <_init+0x15> 400410: e8 4b 00 00 00 callq 400460 <__gmon_start__@plt> 400415: 48 83 c4 08 add $0x8,%rsp 400419: c3 retq Disassembly of section .plt: 0000000000400420 <.plt>: 400420: ff 35 e2 0b 20 00 pushq 0x200be2(%rip) # 601008 <_GLOBAL_OFFSET_TABLE_+0x8> 400426: ff 25 e4 0b 20 00 jmpq *0x200be4(%rip) # 601010 <_GLOBAL_OFFSET_TABLE_+0x10> 40042c: 0f 1f 40 00 nopl 0x0(%rax) 0000000000400430 <puts@plt>: 400430: ff 25 e2 0b 20 00 jmpq *0x200be2(%rip) # 601018 <puts@GLIBC_2.2.5> 400436: 68 00 00 00 00 pushq $0x0 40043b: e9 e0 ff ff ff jmpq 400420 <.plt> 0000000000400440 <system@plt>: 400440: ff 25 da 0b 20 00 jmpq *0x200bda(%rip) # 601020 <system@GLIBC_2.2.5> 400446: 68 01 00 00 00 pushq $0x1 40044b: e9 d0 ff ff ff jmpq 400420 <.plt> 0000000000400450 <__libc_start_main@plt>: 400450: ff 25 d2 0b 20 00 jmpq *0x200bd2(%rip) # 601028 <__libc_start_main@GLIBC_2.2.5> 400456: 68 02 00 00 00 pushq $0x2 40045b: e9 c0 ff ff ff jmpq 400420 <.plt> 0000000000400460 <__gmon_start__@plt>: 400460: ff 25 ca 0b 20 00 jmpq *0x200bca(%rip) # 601030 <__gmon_start__> 400466: 68 03 00 00 00 pushq $0x3 40046b: e9 b0 ff ff ff jmpq 400420 <.plt> Disassembly of section .text: 0000000000400470 <_start>: 400470: 31 ed xor %ebp,%ebp 400472: 49 89 d1 mov %rdx,%r9 400475: 5e pop %rsi 400476: 48 89 e2 mov %rsp,%rdx 400479: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp 40047d: 50 push %rax 40047e: 54 push %rsp 40047f: 49 c7 c0 f0 05 40 00 mov $0x4005f0,%r8 400486: 48 c7 c1 80 05 40 00 mov $0x400580,%rcx 40048d: 48 c7 c7 47 05 40 00 mov $0x400547,%rdi 400494: e8 b7 ff ff ff callq 400450 <__libc_start_main@plt> 400499: f4 hlt 40049a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) 00000000004004a0 <deregister_tm_clones>: 4004a0: 55 push %rbp 4004a1: b8 48 10 60 00 mov $0x601048,%eax 4004a6: 48 3d 48 10 60 00 cmp $0x601048,%rax 4004ac: 48 89 e5 mov %rsp,%rbp 4004af: 74 17 je 4004c8 <deregister_tm_clones+0x28> 4004b1: b8 00 00 00 00 mov $0x0,%eax 4004b6: 48 85 c0 test %rax,%rax 4004b9: 74 0d je 4004c8 <deregister_tm_clones+0x28> 4004bb: 5d pop %rbp 4004bc: bf 48 10 60 00 mov $0x601048,%edi 4004c1: ff e0 jmpq *%rax 4004c3: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) 4004c8: 5d pop %rbp 4004c9: c3 retq 4004ca: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) 00000000004004d0 <register_tm_clones>: 4004d0: be 48 10 60 00 mov $0x601048,%esi 4004d5: 55 push %rbp 4004d6: 48 81 ee 48 10 60 00 sub $0x601048,%rsi 4004dd: 48 89 e5 mov %rsp,%rbp 4004e0: 48 c1 fe 03 sar $0x3,%rsi 4004e4: 48 89 f0 mov %rsi,%rax 4004e7: 48 c1 e8 3f shr $0x3f,%rax 4004eb: 48 01 c6 add %rax,%rsi 4004ee: 48 d1 fe sar %rsi 4004f1: 74 15 je 400508 <register_tm_clones+0x38> 4004f3: b8 00 00 00 00 mov $0x0,%eax 4004f8: 48 85 c0 test %rax,%rax 4004fb: 74 0b je 400508 <register_tm_clones+0x38> 4004fd: 5d pop %rbp 4004fe: bf 48 10 60 00 mov $0x601048,%edi 400503: ff e0 jmpq *%rax 400505: 0f 1f 00 nopl (%rax) 400508: 5d pop %rbp 400509: c3 retq 40050a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) 0000000000400510 <__do_global_dtors_aux>: 400510: 80 3d 31 0b 20 00 00 cmpb $0x0,0x200b31(%rip) # 601048 <__TMC_END__> 400517: 75 17 jne 400530 <__do_global_dtors_aux+0x20> 400519: 55 push %rbp 40051a: 48 89 e5 mov %rsp,%rbp 40051d: e8 7e ff ff ff callq 4004a0 <deregister_tm_clones> 400522: c6 05 1f 0b 20 00 01 movb $0x1,0x200b1f(%rip) # 601048 <__TMC_END__> 400529: 5d pop %rbp 40052a: c3 retq 40052b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) 400530: f3 c3 repz retq 400532: 0f 1f 40 00 nopl 0x0(%rax) 400536: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 40053d: 00 00 00 0000000000400540 <frame_dummy>: 400540: 55 push %rbp 400541: 48 89 e5 mov %rsp,%rbp 400544: 5d pop %rbp 400545: eb 89 jmp 4004d0 <register_tm_clones> 0000000000400547 <main>: 400547: 55 push %rbp 400548: 48 89 e5 mov %rsp,%rbp 40054b: 48 83 ec 10 sub $0x10,%rsp 40054f: bf 08 06 40 00 mov $0x400608,%edi 400554: e8 e7 fe ff ff callq 400440 <system@plt> 400559: 89 45 fc mov %eax,-0x4(%rbp) 40055c: 83 7d fc 00 cmpl $0x0,-0x4(%rbp) 400560: 75 0c jne 40056e <main+0x27> 400562: bf 20 06 40 00 mov $0x400620,%edi 400567: e8 c4 fe ff ff callq 400430 <puts@plt> 40056c: eb 0a jmp 400578 <main+0x31> 40056e: bf 48 06 40 00 mov $0x400648,%edi 400573: e8 b8 fe ff ff callq 400430 <puts@plt> 400578: b8 00 00 00 00 mov $0x0,%eax 40057d: c9 leaveq 40057e: c3 retq 40057f: 90 nop 0000000000400580 <__libc_csu_init>: 400580: 41 57 push %r15 400582: 41 89 ff mov %edi,%r15d 400585: 41 56 push %r14 400587: 49 89 f6 mov %rsi,%r14 40058a: 41 55 push %r13 40058c: 49 89 d5 mov %rdx,%r13 40058f: 41 54 push %r12 400591: 4c 8d 25 80 08 20 00 lea 0x200880(%rip),%r12 # 600e18 <__frame_dummy_init_array_entry> 400598: 55 push %rbp 400599: 48 8d 2d 80 08 20 00 lea 0x200880(%rip),%rbp # 600e20 <__init_array_end> 4005a0: 53 push %rbx 4005a1: 4c 29 e5 sub %r12,%rbp 4005a4: 31 db xor %ebx,%ebx 4005a6: 48 c1 fd 03 sar $0x3,%rbp 4005aa: 48 83 ec 08 sub $0x8,%rsp 4005ae: e8 4d fe ff ff callq 400400 <_init> 4005b3: 48 85 ed test %rbp,%rbp 4005b6: 74 1e je 4005d6 <__libc_csu_init+0x56> 4005b8: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1) 4005bf: 00 4005c0: 4c 89 ea mov %r13,%rdx 4005c3: 4c 89 f6 mov %r14,%rsi 4005c6: 44 89 ff mov %r15d,%edi 4005c9: 41 ff 14 dc callq *(%r12,%rbx,8) 4005cd: 48 83 c3 01 add $0x1,%rbx 4005d1: 48 39 eb cmp %rbp,%rbx 4005d4: 75 ea jne 4005c0 <__libc_csu_init+0x40> 4005d6: 48 83 c4 08 add $0x8,%rsp 4005da: 5b pop %rbx 4005db: 5d pop %rbp 4005dc: 41 5c pop %r12 4005de: 41 5d pop %r13 4005e0: 41 5e pop %r14 4005e2: 41 5f pop %r15 4005e4: c3 retq 4005e5: 90 nop 4005e6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 4005ed: 00 00 00 00000000004005f0 <__libc_csu_fini>: 4005f0: f3 c3 repz retq Disassembly of section .fini: 00000000004005f4 <_fini>: 4005f4: 48 83 ec 08 sub $0x8,%rsp 4005f8: 48 83 c4 08 add $0x8,%rsp 4005fc: c3 retq [root@mcwtest ares]#
c语言获取监控系统数据
在C语言中获取系统监控数据通常涉及直接调用系统API或者读取特定的系统文件。下面是一些常见的方法来获取不同类型的系统监控数据:
1. 获取CPU使用率和内存使用情况
在Linux系统中,你可以通过读取/proc/stat
和/proc/meminfo
文件来获取CPU使用率和内存使用情况。这些文件提供了关于系统状态和性能的详细信息。
例如,以下是一个简单的示例代码,用于获取CPU使用率:
#include <stdio.h> #include <stdlib.h> #include <string.h> double get_cpu_usage() { FILE *fp; char buffer[1024]; unsigned long long cpu_time[4] = {0}; unsigned long long idle_time, total_time, prev_idle_time = 0, prev_total_time = 0; double cpu_usage = 0.0; // 读取/proc/stat文件第一次 fp = fopen("/proc/stat", "r"); if (fp == NULL) { perror("Error opening /proc/stat"); exit(EXIT_FAILURE); } if (fscanf(fp, "cpu %llu %llu %llu %llu", &cpu_time[0], &cpu_time[1], &cpu_time[2], &cpu_time[3]) != 4) { perror("Error reading /proc/stat"); fclose(fp); exit(EXIT_FAILURE); } fclose(fp); // 保存第一次的idle和total时间 idle_time = cpu_time[3]; total_time = cpu_time[0] + cpu_time[1] + cpu_time[2] + cpu_time[3]; // 稍后再读取一次/proc/stat文件 sleep(1); // 等待一秒钟 fp = fopen("/proc/stat", "r"); if (fp == NULL) { perror("Error opening /proc/stat"); exit(EXIT_FAILURE); } if (fscanf(fp, "cpu %llu %llu %llu %llu", &cpu_time[0], &cpu_time[1], &cpu_time[2], &cpu_time[3]) != 4) { perror("Error reading /proc/stat"); fclose(fp); exit(EXIT_FAILURE); } fclose(fp); // 计算新的idle和total时间 unsigned long long new_idle_time = cpu_time[3]; unsigned long long new_total_time = cpu_time[0] + cpu_time[1] + cpu_time[2] + cpu_time[3]; // 计算CPU使用率 if (new_total_time != prev_total_time) { cpu_usage = (double)(new_total_time - prev_total_time - (new_idle_time - prev_idle_time)) / (double)(new_total_time - prev_total_time) * 100.0; } // 更新之前的idle和total时间,以便下次计算 prev_idle_time = new_idle_time; prev_total_time = new_total_time; return cpu_usage; } int main() { double cpu_usage = get_cpu_usage(); printf("CPU Usage: %.2f%%\n", cpu_usage); return 0; }
[root@mcwtest xiaoma]# gcc cpumem.c -o cpumem-mcw cpumem.c: In function ‘get_cpu_usage’: cpumem.c:30:5: warning: implicit declaration of function ‘sleep’; did you mean ‘strsep’? [-Wimplicit-function-declaration] sleep(1); ^~~~~ strsep [root@mcwtest xiaoma]# ls cpumem.c cpumem-mcw [root@mcwtest xiaoma]# ./cpumem-mcw CPU Usage: 1.26% [root@mcwtest xiaoma]# vmstat procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 1 0 0 204204 260244 2625456 0 0 1 15 1 5 1 1 99 0 0 [root@mcwtest xiaoma]#
2. 获取磁盘使用情况
在Linux系统中,你可以读取/proc/mounts
和/proc/diskstats
文件,或者使用statvfs
函数来获取磁盘使用情况。下面是一个使用statvfs
函数的示例:
#include <stdio.h> #include <sys/statvfs.h> int main() { struct statvfs buf; if (statvfs("/", &buf) != 0) { perror("Error in statvfs"); return 1; } long long total_bytes = buf.f_frsize * buf.f_blocks; // 总字节数 long long free_bytes = buf.f_frsize * buf.f_bavail; // 可用字节数 long long used_bytes = total_bytes - free_bytes; // 已用字节数 printf("Total space: %lld bytes\n", total_bytes);
在C语言中,你可以使用statvfs
函数来获取磁盘的使用情况。statvfs
函数用于获取文件系统的统计信息,包括磁盘的总大小、可用空间、已用空间等。下面是一个简单的示例代码,演示如何使用statvfs
函数来获取根目录(/
)的磁盘使用情况:
#include <stdio.h> #include <sys/statvfs.h> int main() { struct statvfs buf; if (statvfs("/", &buf) != 0) { perror("Error in statvfs"); return 1; } // 获取磁盘总大小(以字节为单位) unsigned long long total_bytes = (unsigned long long)buf.f_frsize * buf.f_blocks; // 获取磁盘可用空间(以字节为单位) unsigned long long available_bytes = (unsigned long long)buf.f_frsize * buf.f_bavail; // 获取磁盘已用空间(以字节为单位) unsigned long long used_bytes = total_bytes - available_bytes; // 输出结果 printf("Total space: %llu bytes\n", total_bytes); printf("Available space: %llu bytes\n", available_bytes); printf("Used space: %llu bytes\n", used_bytes); // 如果你想以更友好的单位(如GB、MB)显示这些信息,可以添加转换代码 // 例如,转换为GB: double total_gb = total_bytes / (1024.0 * 1024.0 * 1024.0); double available_gb = available_bytes / (1024.0 * 1024.0 * 1024.0); double used_gb = used_bytes / (1024.0 * 1024.0 * 1024.0); printf("Total space: %.2f GB\n", total_gb); printf("Available space: %.2f GB\n", available_gb); printf("Used space: %.2f GB\n", used_gb); return 0; }
在这段代码中,statvfs
函数被用来获取根目录(/
)的磁盘使用情况,并将其存储在一个statvfs
结构体中。然后,你可以从这个结构体中提取出总大小、可用空间和已用空间的信息。
请注意,statvfs
函数在类Unix系统(如Linux)上可用,但在Windows上不可用。如果你在Windows上编程,你需要使用Windows API来获取磁盘使用情况,例如使用GetDiskFreeSpaceEx
函数。
另外,为了以更友好的单位显示磁盘空间,代码示例中还包括了将字节转换为GB的转换逻辑。你可以根据需要调整这些转换逻辑,以显示MB、KB或其他单位。
[root@mcwtest xiaoma]# ls cpumem.c cpumem-mcw mcwdisk.c [root@mcwtest xiaoma]# vim mcwdisk.c [root@mcwtest xiaoma]# cat mcwdisk.c #include <stdio.h> #include <sys/statvfs.h> int main() { struct statvfs buf; if (statvfs("/", &buf) != 0) { perror("Error in statvfs"); return 1; } unsigned long long total_bytes = (unsigned long long)buf.f_frsize * buf.f_blocks; unsigned long long available_bytes = (unsigned long long)buf.f_frsize * buf.f_bavail; unsigned long long used_bytes = total_bytes - available_bytes; printf("Total space: %llu bytes\n", total_bytes); printf("Available space: %llu bytes\n", available_bytes); printf("Used space: %llu bytes\n", used_bytes); double total_gb = total_bytes / (1024.0 * 1024.0 * 1024.0); double available_gb = available_bytes / (1024.0 * 1024.0 * 1024.0); double used_gb = used_bytes / (1024.0 * 1024.0 * 1024.0); printf("Total space: %.2f GB\n", total_gb); printf("Available space: %.2f GB\n", available_gb); printf("Used space: %.2f GB\n", used_gb); return 0; } [root@mcwtest xiaoma]# ls cpumem.c cpumem-mcw mcwdisk.c [root@mcwtest xiaoma]# gcc mcwdisk.c -o mcwdisk [root@mcwtest xiaoma]# ls cpumem.c cpumem-mcw mcwdisk mcwdisk.c [root@mcwtest xiaoma]# ./mcwdisk Total space: 51651293184 bytes Available space: 36776316928 bytes Used space: 14874976256 bytes Total space: 48.10 GB Available space: 34.25 GB Used space: 13.85 GB [root@mcwtest xiaoma]# df -h Filesystem Size Used Avail Use% Mounted on devtmpfs 2.0G 0 2.0G 0% /dev tmpfs 2.0G 4.0K 2.0G 1% /dev/shm tmpfs 2.0G 201M 1.8G 11% /run tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup /dev/vda3 49G 12G 35G 26% / /dev/vda2 976M 168M 742M 19% /boot tmpfs 394M 0 394M 0% /run/user/3001 [root@mcwtest xiaoma]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT vda 252:0 0 50G 0 disk ├─vda2 252:2 0 1G 0 part /boot ├─vda3 252:3 0 49G 0 part / └─vda1 252:1 0 1M 0 part [root@mcwtest xiaoma]#
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?