Linux程序设计 学习笔记 (一)

Linux程序设计 学习笔记 (一)

Posted by 敬方 on August 13, 2019

Linux 程序设计 阅读笔记

参考链接:

第一章 入门

1.1.1 unix

参考链接: POSIX标准总体分析;POSIX

unix系统特点

  • 简单性:
  • 集中性:
  • 可重用组件
  • 过滤器
  • 开放的文件格式
  • 灵活性

几乎所有的UNIX编写的程序都可以在Linux上编译运行

GNU项目软件:

  • GCC:GNU编译器集,包括GUN c
  • G++:c++编译器,是GCC的一部分。
  • GDB:源代码级别的调试器
  • GNU make:NUIX make 的免费版本
  • Bison:与UNIX yacc兼容的语法分析生成器。
  • bash:命令与解释器
  • GNU Emacs:文本编辑器计环境

linux支持的编程语言:

linux支持的编程语言

普通用户可执行程序搜索路径

  • /bin:二进制文件目录,用于存放启动系统时用到的程序
  • /usr/bin:用户二进制文件目录,用于存放启动系统时用到的程序
  • /usr/local/bin:本地二进制目录,用于存放软件安装的程序
  • /usr/sbin/sbin:root登录后的PATH变量和程序存在的路径
  • /opt:第三方应用程序,可能被安装的目录。

注意当操作系统升级的时候,只有目录/opt/usr/local里面的内容需要保留,对于系统级应用程序,建议放在/usr/local中,个人应用程序放在home文件夹中。

1.2.4 开发系统引导

参考链接: Linux系统目录结构说明;Linux 系统目录结构;ubuntu获取源码方法

头文件位置:/usr/include,特定版本依赖,一般都在/usr/include/sys或者/usr/include/linux

库文件:一般存储在/lib/usr/lib目录中。包括.a静态函数库和.so动态函数库。

注意:当静态库被多个应用程序使用时,内存中就会存在同一函数的多个副本,将大量消耗内存和磁盘空间。

额外的搜索路径可以在/etc/ld.so.conf中配置。

第二章 shell程序设计

Linux中一般工具的开发都是先用shell实现,当追求速度时,再使用c/c++,Perl或者其它语言实现。

内核应用程序关系

shell中*匹配字符串,?匹配单个字符,[]{}匹配多个字符串。

more `grep -l POSIX`

#等价于

more ${grep -l POSIX *}

脚本中第一行的#!/bin/bash告诉脚本它的执行软件。注意绝对路径不要超过32个字符,因为老版本的识别不了。

shell中变量直接声明,使用时使用$,赋值时等号两边不能有空格。 shell中”'”只是输出字符串,”"”进行变量解析。

环境变量

环境变量表格

参数变量 当脚本运行时带有参数时,一些额外的变量就会被创建。环境变量$#始终存在,只是当无参数传递时为0;

输入参数变化

$@和$*之间的区别

注意:$#是未知变量的个数

下面是简单的测试脚本程序

#!/bin/bash

#shell file name try_var

salutation="hello"
echo $salutation
echo "The parameter 0 is : $0"
echo "The parameter 1 is : $1"
echo "The parameter 2 is : $2"
echo "The parameter list is : $*"
echo "The parameter list is : $@"
echo "The user's home directory is $HOME "

echo "Please enter a new greeting "
read salutation
echo $salutation
echo "The script is now complete"
exit 0


输入: ./try_var.sh 1 2 3 输出:

hello
The parameter 0 is : ./try_var.sh
The parameter 1 is : 1
The parameter 2 is : 2
The parameter list is : 1 2 3
The user's home directory is /home/wangpengcheng 
Please enter a new greeting 
123
123
The script is now complete

2.6.2 条件

test[命令,使用[时,通常以]符号来结尾。test用的较少。例如:

#!/bin/bash
#检查是否存在文件
if test -f fred.c
then
    ...
fi

#还可以写成下面这样

if [ -f fred.c ]
then
...
fi

注意命令使用时后面必须存在空格。

常见比较表达式

常见比较

文件测试

2.6.3 控制结构


if condition
then 
    statements1
elif condition
    statements2
else
    statements3
fi


注意对百年来那个字符串进行比较时,最好使用""让变量初始化。

可以使用printf代替echo就可以自定义,换行符。

for语句

for variable in value
do
    statements
done

示例:

#!/bin/bash

for file in $(ls f*.sh);
do
    lpr $file
done
exit 0

while语句


while condition do
    statements
done

untill语句

循环执行,直到满足条件


until [[ condition ]]; do
    statements
done

case语句


case variable in
    pattern [ | pattern ] ...) statements;;
    pattern [ | pattern ] ...) statements;;
    ...
esac

注意每个模式都应该以双分号结尾。

使用示例:

#!/bin/bash

echo "Is it morning? Please answer yes or no"
read timeofday

case "$timeofday" in
    yes | y | Yes | TES )   
        echo "test"
        echo "Good morning";;
    n* | N* )               echo "Good Afternoon";;
    * )                     echo "Sorry,answer not reconized";;
esac
exit 0

列表命令

  • AND 列表:&&执行and条件,注意前后有空格
  • OR 列表: || 直到有一条命令成功运行。

语句块

使用{}来构造执行语句块。

2.6.4 函数

格式:

function_name()
{
    statements
}

注意:当一个函数被调用时,脚本程序的位置参数($*、$@、$#、$1、$2等)会被替换为函数的参数。这也是读取传递给函数的参数的办法。当函数执行完毕后,参数会恢复为它们先前的值。

函数操作字符串,一般是提前声明变量,或者使用local关键子在shell中声明局部变量,说明变量范围。否则都是按照全局变量处理。 下面是一个简单的示例:

#!/bin/bash

# file name yes_or_no 

yes_or_no(){
    echo "Is your name $* ?"
    while [[ true ]]; do
         echo -n "Enter yes or no: "
         read x
         case "$x" in
             y | yes ) return 0;;
             n | no ) return 1;;
             * ) echo "Answer yes or no"
         esac
     done 
}

echo "Original parameter are $* "
#将脚本输入的第一个参数,函数的第一个参数

if yes_or_no "$1"
then
    echo "Hi $1 , nice name"
else
    echo "Never mind"
fi

exit 0
# 输入: ./yes_or_no.sh  Rick Neil
# 输出

# Original parameter are Rick Neil 
# Is your name Rick ?
# Enter yes or no: y
# Hi ./yes_or_no.sh  Rick Neil, nice name

2.6.5 命令

shell脚本中可以执行的命令分为两类:

  • 内置命令:shell中内置的命令,linux中大多数内部命令都提供了外部版本
  • 外置命令:非shell中的内置命令。

常用命令

  • break:跳出一层循环。
  • ::是一个空命令。相当于true的别名,运行的比true快。例如:${var:=value}没有’:’,shell将试图把$var作为一条命令来处理。
  • continue:跳过剩下的直接进行下一次循环。
  • .:表示在当前shell中执行命令.命令和source命令功能相同,可以避免创建shell执行时,由于新的环境所造成的变量丢失。例如:. ./shell_script.sh脚本中执行的变量会在当前shell中生效。
  • echo: 现代脚本中推荐使用printf命令。
  • eval:允许你对参数进行求值,相当于一个额外的$
#!/bin/bash

foo=10
x=foo
y='$'$x
echo $y

eval z='$'$x
echo $z 
# 输出: $foo 10

注意:z='$'$x单独的输出是foo基本无效。

  • exec:
    • 将当前shell替换为一个不同的程序,exec后面的代码不会执行。如:exec wall "Thanks for all"
    • 修改当前文件描述符:exec 3< afile
  • exit n:脚本以结束码n退出。0表示成功退出,1-125是脚本可以使用的错误代码。其余数字有保留含义。
  • export:将作为它参数的变量导出到子shell中,并使之在子shell中有效。主要是设置环境变量,这个环境变量可以被当前程序调用的其它脚本程序看到。
  • expr:将他的参数,当做一个表达式来进行求值;如:
x=`expr $x +1 ` 

#或

x=$(expr $x + 1)

可以使用$()代替反引号。在比较新的脚本程序送expr命令被$(())命令所代替。

常见表达式操作

  • printf:字符输出命令;例如prinf "%s \n" hello

支持的转义序列

字符转换限定符

  • return:函数的返回参数,没有指定参数则默认返回最后一条命令的退出码。
  • set:设置shell参数变量,可以结合$*$2等来进行参数变量的设置。
  • shift:所有变量左移一个位置,将$2变为$1$3变为$2
  • trap:tarp command signal,接收signal信号,再采取command行动。

signal信号

  • unset:从环境中删除变量或者函数。
  • find:find [path] [option] [testss] [actions]找寻。

find命令参数选项

find测试部分

find操作符

find动作

  • grepgrep [option] PATTERN [FILES]

grep命令参数

正则表达式

正则表达式含义

特殊匹配模式 特殊匹配模式

-E扩展匹配选项:

匹配选项

例如:

#查找以e结尾的字符

grep e$ words2.txt
#查找a-z重复10次的匹配字符

grep -E [a-z]\{10\} words2.txt

2.6.6 命令的执行

脚本中获取命令结果可以使用$() ,例如$(pwd)获取当前输出文件夹。

2.6.6.1 算术扩展

使用expr或者$(())可以进行算术扩展。

${}的使用:

扩展参数列表

2.6.8 调试脚本程序

脚本程序调试选项

2.7 迈向图形化:dialog工具

使用dialog可以在shell中创建图形工具并且实现交互;

dialog --msgbox "hello word" 9 18

对话框主要类型

对话框参数

使用示例:

dialog --title "Check me" --checklist "Pick Numbers" 15 25 3 1 "one" "off" 2 "two" "on" 3 "tree" "off"

2.8 综合应用

代码地址