Linux C 基础

Linux C 基础

1 软件包管理机制

1.1 dpkg

  • 功能: dpkg 是一个低级的包管理工具,用于在Debian系统中安装、卸载和管理软件包。
  • 使用方式: 典型的使用包括使用dpkg -i来安装软件包,dpkg -r来卸载软件包,以及dpkg -l来列出已安装的软件包。
  • 注意事项: dpkg处理软件包的安装和卸载,但不会解决软件包依赖关系,需要手动解决依赖问题。
  • 相关命令
dpkg -i <package>  安装一个在本地文件系统上存在的Debian软件包
dpkg -r <package>  移除一个已经安装的软件包
dpkg -P <package>  移除已安装软件包及配置文件
dpkg -L <package>  列出安装的软件包清单
dpkg -s <package>  显出软件包的安装状态

1.2 apt

  • 功能: apt 是一个高级的包管理工具,构建在dpkg之上,用于简化软件包的安装、升级和依赖关系的管理。
  • 使用方式: 典型的使用包括使用apt install来安装软件包,apt remove来卸载软件包,以及apt updateapt upgrade来更新软件包。
  • 注意事项: apt会自动解决软件包之间的依赖关系,提供了更高级、用户友好的接口。
  • 工作原理:•在Ubuntu系统中,使用软件源配置文件/etc/apt/sources.list 列出最合适访问的镜像站点地址。软件源配置文件只是告知Ubuntu系统可以访问的镜像站点地址。但那些镜像站点都拥有什么软件资源并不清楚。若是每安装一个软件包,就在服务器上寻找一边,效率是很低的。因而,就有必要为这些软件资源列个清单(建立索引文件),以便本地主机查询。
  • 建立文件清单:使用apt-get update命令会扫描每一个软件源服务器,并为该服务器所具有软件包资源建立索引文件,存放在本地的/var/lib/apt/lists/目录中。
    常用命令
    ![[Pasted image 20231228224843.png]]
    常用选项
    ![[Pasted image 20231228225237.png]]
    --reinstall可以修复已损坏的软件包和升级软件包中的文件的最近版本
    --purge不仅卸载软件包及其依赖项,还卸载对应的配置文件
    修复软件包依赖关系:
# 先检查软件包之间的依赖关系,再进行修复
apt-get check
apt-get -f install

查看已经软件包缓冲区和清理缓冲区:

ls /var/cache/apt/archives/

apt-get clean

# 只保留最新版本的软件包,其余版本全都清除
apt-get autoclean

查看软件包源

ls /var/lib/apt/lists/*
  • 查询软件包信息:使用apt-cache命令完成查询软件源和软件包的相关信息
    ![[Pasted image 20231228225856.png]]

2 shell基本命令

shell是一个命令行解释器,将用户命令解析为操作系统所能理解的指令,实现用户与操作系统的交互。
命令格式Command [-Options] Argument1 Argument2
- 多个命令在一行书写:使用’;‘隔开
- 不能写完一行:使用’\'隔开
常用命令
- 历史命令:
- 查询历史命令:history->history <number>
- 删除某条历史命令:histroy -d <number>
- 查看历史命令容量:echo $HISTORYSIZE

2.1 通配符

使用场景:对多个文件进行条件筛选
![[Pasted image 20231229151655.png]]

2.2 管道

使用场景:命令的串行使用,一般用于多个命令完成一项任务且命令间有同步关系。关键符号:‘|’
ls /usr/bin | wc -w

2.3 输入\输出重定向

使用场景:将标准的输入、输出和错误信息用于其他设备(不局限于控制台,还有文件、打印机等输入输出设备)
•输入/输出重定向是改变shell命令或程序默认的标准输入/输出目标,重新定向到新的目标。
•linux中默认的标准输入定义为键盘,标准输出定义为终端窗口。
•用户可以为当前操作改变输入或输出,迫使某个特定命令的输入或输出来源为外部文件。
![[Pasted image 20231229152237.png]]
示例

# cat没有选项和参数时可以作为标准输入/输出使用
$ cat  # 键盘输入,屏幕输出
hello!
hello!
$ cat > file.txt # 键盘输入的内容定位到file文件中
$ cat < file.txt # file文件作为输入,cat接收file中的内容并显示到屏幕上

2.4 命令置换

•命令替换是将一个命令的输出作为另一个命令的参数。命令格式如下所示。
格式

$ command1 `command2`
$ ls `pwd`

3 shell编程

  • shell的本质:shell命令的有序集合

3.1 变量

  • 所有变量都会被解释字符串
    变量类型:
    • 用户自定义的变量:
var.sh
# 1 定义使用和不使用变量
#!/bin/sh
COUNT=1
echo $COUNT  # 使用变量

DATE=`date`  # 命令执行的结果返回给变量
echo $DATE

unset COUNT  # 不使用变量
echo $COUNT
# 输出
./var.sh
1
Tue Jan 2 05:40:25 PM CST 2024
- 位置变量或预定义变量
	 $0   与键入的命令行一样,包含脚本文件名
	 $1,$2,……$9  分别包含第一个到第九个命令行参数
	 $#   包含命令行参数的个数
	 $@   包含所有命令行参数:“$1,$2,……$9”
	 $?   包含前一个命令的退出状态
	 $*   包含所有命令行参数:“$1,$2,……$9”
	 $$   包含正在执行进程的ID号	
- 环境变量
     HOME: /etc/passwd文件中列出的用户主目录 
	 IFS:Internal Field Separator, 默认为空格,tab及换行符
	 PATH :shell搜索路径
	 PS1,PS2:默认提示符($)及换行提示符(>) 
	 TERM:终端类型,常用的有vt100,ansi,vt200,xterm等 

3.2 功能语句

  • 说明性语句(注释):
    • 以"#"开头:告诉OS用哪种类型的shell来解释执行该程序
#! /bin/sh
  • 功能性语句:
    • read:标准输入
#!/bin/sh

echo "input year month day"
read year month day
echo $year $month $day
echo `date`

read -p "Enter your name: " name
echo "Hello, $name!"

./read.sh
input year month day
2023 12 31  # 键盘输入
2023 12 31
Tue Jan 2 08:22:36 PM CST 2024
GXL # 键盘输入
Hello, GXL!
- expr:数学计算
  • 算术运算命令expr主要用于进行简单的整数运算,包括加(+)、减(-)、乘(*)、整除(/)和求模(%)等操作
expr.sh
#!/bin/sh
var1=$1
var2=$2
sum=`expr $var1 \* $var2`
echo "$sum"

./expr.sh
8
  • 测试语句:
    • 测试字符串
s1 = s2 	测试两个字符串的内容是否完全一样
s1 != s2	测试两个字符串的内容是否有差异
-z s1 	测试s1 字符串的长度是否为0
-n s1 	测试s1 字符串的长度是否不为0

test.sh
#!/bin/bash

test $1 = "yes"
echo $?
test $2 -lt 18
echo $?
test -d $3
echo $?

./test.sh
0
0
0
- 测试整数
a -eq b 		测试a 与b 是否相等
a -ne b		测试a 与b 是否不相等
a -gt b 		测试a 是否大于b
a -ge b 		测试a 是否大于等于b
a -lt b 		测试a 是否小于b
a -le b 		测试a 是否小于等于b
- 文件属性测试
-d name    测试name 是否为一个目录
-e name    测试一个文件是否存在
-f name    测试name 是否为普通文件
-L name    测试name 是否为符号链接
-r name    测试name 文件是否存在且为可读
-w name    测试name 文件是否存在且为可写
-x name    测试name 文件是否存在且为可执行
-s name    测试name 文件是否存在且其长度不为0
f1 -nt f2  测试文件f1 是否比文件f2 更新
f1 -ot f2  测试文件f1 是否比文件f2 更旧

3.3 分支语句

  • 结构性语句:
    • 条件语句:
if.sh
#!/bin/bash
var1=$1
if [ -f $var1 ]
then
        echo "The file is exists: $var1"
elif [-d $var1 ]
then
        echo "The diretory is  exites: $var1"
else
        echo "It is not."
fi

./if.sh if.sh
The file is exists: if.sh
- 多路分支语句:
书写规则
	 case…esac 
    		多路分支语句case用于多重条件测试, 语法结构清晰自然.  其语法为:
     		case   字符串变量   in
            		模式1)
                       		命令表1
                        	;;
            		模式2 | 模式3)   
                       		命令表2
                        	;;
             		……
            		模式n)
                       		命令表n
                        	;;
    		esac
	注:
	   1)case语句只能检测字符串变量
	   2)各模式中可用文件名元字符,以右括号结束
	   3)一次可以匹配多个模式用“|”分开
	   4)命令表以单独的双分号行结束,退出case语句
	   5)模式 n常写为字符* 表示所有其它模式
	   6)最后一个双分号行可以省略
case.sh
#!/bin/bash

grade=`expr $1 / 10`
case $grade in
	9|10)
		echo "A+"
		;;
	8)
		echo "A"
		;;
	7)
		echo "A-"
		;;
	5|6)
		echo "B"
		;;
	*)
		echo "C"
		;;
esac

./case.sh 80
A
- 循环语句:
	- for
  • 1)当循环次数已知或确定时,使用for循环语句来多次执行一条或一组命令。
    循环体由语句括号do和done来限定。格式为:
    for 变量名 in 单词表
    do
    命令表
    done
    2)变量依次取单词表中的各个单词, 每取一次单词, 就执行一次循环体中的命令.
    循环次数由单词表中的单词数确定. 命令表中的命令可以是一条, 也可以是由分号或换行符分开的多条。
    3)如果单词表是命令行上的所有位置参数时, 可以在for语句中省略 “in 单词表” 部分。
for.sh
#!/bin/bash
if [ ! -d backup ]  # backup目录不存在
then
        mkdir backup
        echo "create d backup success!"
fi
flist=`ls`
echo "$flist"
for file in $flist
do
        if [ $file != "backup" ]
        then
                cp -r $file backup   # 递归复制文件
                echo "$file backuped."
        fi
done
echo "all files backuped."
	- while

语法结构为:
while 命令或表达式
do
命令表
done
1)while语句首先测试其后的命令或表达式的值,如果为真,就执行一次循环体中的命令,
然后再测试该命令或表达式的值,执行循环体,直到该命令或表达式为假时退出循环。
2)while语句的退出状态为命令表中被执行的最后一条命令的退出状态。
- 循环控制语句
- break
- continue

#!/bin/bash
if [ $# != 2 ]   # 输入参数个数必须为2
then
	echo "parameters numbers is not 2."
	exit
fi
base_name=$1  
number=$2
n=1
while [ $n -le $number ]
do
	touch $1_$n
	n=`expr $n + 1`
done

3.4 shell函数

  • 函数调用
    • 直接调用
    • 传参:函数内部中的$1 $2 $3...就不是命令行传的参数而是函数传的参数
# 调用格式
方式1:
value_name=`function_name  [arg1 arg2 … ]`
函数的所有标准输出都传递给了主程序的变量
方式2:
function_name  [arg1  arg2  …  ]
echo   $?
获取函数的返回的状态

func.sh
#!/bin/bash

func()
{
	sum=`expr $1 + $2`
	echo "$1+$2"
	return $sum
}
sum=`func 2 3`
echo $?
echo "$sum"

./func.sh
5
2+3
  • 函数变量的作用域
    默认是全局变量,若需要缩小作用域则在变量之前加local关键字

4 gbd调试工具

(1) 调试器–Gdb调试流程
首先使用gcc对test.c进行编译,注意一定要加上选项‘-g’
# gcc -g test.c -o test
# gdb test
(2) gdb调试流程
查看文件
(gdb) l
设置断点
(gdb) b 6(代码行数)
查看断点情况
(gdb) info b(查看所有设置的断点)
运行代码
(gdb) r(开始运行程序)

查看变量值
    (gdb) p n(已经运行过的变量)
单步运行 
    (gdb) n(函数体外的运行)
    (gdb) s(进入函数体内)
恢复程序运行 
    (gdb) c(执行以后的程序,忽略之后的断点)
帮助 
    (gdb) help [command] 

(3)Gdb的使用切记点
在gcc编译选项中一定要加入‘-g’。
只有在代码处于“运行”或“暂停”状态时才能查看变量值。
设置断点后程序在指定行之前停止
(4)gdb调试
运行被调试程序,设置所有的能影响该程序的参数和变量。
保证被调试程序在指定的条件下停止运行。
当被调试程序停止时,让开发工程师检查发生了什么。
根据每次调试器的提示信息来做响应的改变,以便修正某个错误引起的问题

5 条件编译

(1)编译器根据条件的真假决定是否编译相关的代码,
常见的条件编译有两种方法:

一、根据宏是否定义,其语法如下:
#ifdef  <macro>
  ……
#else
 ……
#endif

compile.c
#include <stdio.h>
#define _DEBUG_

int main(int argc, char *argv[])
{
	#ifdef  _DEBUG_
	 printf("The macro _DEBUG_ is defined\n");
	 #else
	 printf("The macro _DEBUG_ is not defined\n");
	 #endif
	 return 0;
}

gcc complie.c -o compile
./compile
The macro _DEBUG_ is defined

二、根据宏的值,其语法如下:
#if  <macro>
 ……
#else
   ……
#endif

complie.c
#include <stdio.h>
#define _DEBUG_ 0

int main(int argc, char *argv[])
{
	#if  _DEBUG_
	 printf("The macro _DEBUG_ is defined\n");
	 #else 
	 printf("The macro _DEBUG_ is not defined\n");
	 #endif
	 return 0;
}

gcc complie.c -o complie
./compile
The macro _DEBUG_ is not defined
  • 14
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值