目錄

統一宣告:

部落格轉載 聲 明 : 本部落格部分內容來源於網路、書籍、及各類手冊。

        內容宗旨為方便查詢、總結備份、開源分享。

        部分轉載內容均有註明出處,如有侵權請聯絡部落格告知並刪除,謝謝!

百度雲盤提取碼:統一提取碼: ziyu

一、Linux

1.1、嵌入式

嵌入式:計算機應用為中心、軟硬體可裁剪的系統。

1.2、什麼是Linux

  • Linux 多工、分時 的一個作業系統
  • GNU GNU is Not Unix 它是一個組織;
  • GPL 是一種協議。

1.3、Linux發行版

  • Linux本身指的是一個作業系統核心,只有核心是無法使用的。
  • 我們系統使用作業系統一個包含核心和一批有用的應用集合,這就叫Linux發行版。

    Ubuntu、Redhat就是Linux的不同的發行版。
  • Red Hat 伺服器
  • unbutu 桌面效能好 “人道主義”。
  • debian

1.4、Linux體系結構

--------------------------------------------	[0-3G]	0XC000 0000
應用層
app程式、shell命令、shell指令碼、程式
| |
| |
| |
核心層---------------------------系統呼叫--- [3-4G] 0xffff ffff(代表4G) 1 0000 0000
檔案管理
記憶體管理
程序管理 --> 程式的一次執行過程
硬體管理
網路管理
--------------------------------------------
硬體層
LED LCD CAMERA 滑鼠 鍵盤

1.5、虛擬4G記憶體

-------------	4G
核心
------------- 3G
棧區 自動開闢自動釋放
-------------
堆區 手動malloc
------------- 靜態區/資料區 全域性/靜態 -------------
字串常量
-------------
程式碼段
------------- 0

1.6、shell 命令

whoami	我是誰
ls
-a
-l
-r 遞迴查詢
-i inode 一個編號,一種節點
-lh
pwd
cd
cd dir_name
cd 路徑 絕對路徑 相對路徑
cd ~ 返回目錄
cd
cd .
cd ..
cd - 返回上一步
mkdir
-p 遞迴建立
rm mkdir dir_name 刪除空目錄
rm -r dir_name
touch file_name
rm file_name
cp
cp 路徑 路徑 複製檔案
cp -r
-a 目錄的複製
mv
mv 路徑 路徑
exit 退出
echo 輸出
su 切換使用者
sudo 許可權
clear 清屏 快捷鍵:Ctrl+L

1.7、軟體包的管理

1.7.1、dpkg:(離線安裝)

rxvt        _1%3a2.6.4-14               _i386      .deb
| |
| | 32
| |
軟體名 主版本號 修訂版本號 體系結構 字尾

軟體包安裝:

  sudo dpkg -i 軟體包全稱

解除安裝:

   sudo dpkg -r 軟體名

清除軟體包的配置檔案:

  sudo dpkg -p 軟體名

列舉軟體的相關資訊的清單:

  sudo dpkg -L 軟體名

查詢版本號:

  sudo dpkg -l 軟體名

查詢軟體安裝包的狀態:

  sudo dpkg -s 軟體名

強制安裝:

  sudo dpkg -f 軟體名

虛擬機器自定義伸縮視窗大小

  虛擬機器 --> 首選項 --> 顯示;

  更新 vmare tools

    點選 虛擬機器---> 更新(重灌) VMware tools

    跳轉到一個介面,介面上有VMwareTools-10.3.10-13959562.tar.gz 這個壓縮包,

    把這個安裝包解壓在家目錄 tar -xvf VMwareTools-10.3.10-13959562.tar.gz (一直按enter鍵直到結束)

    結束後生成一個目錄--vmware_tools_distrib, cd 進去這個目錄,再執行 ./vmare_install.pl 這個可執行檔案就可以了;

1.7.2、把windows的檔案複製到Ubuntu中

(1)、拖拽的方式:

  直接把檔案拖到終端,在前面加上 mv 移動到某一個路徑(mv '/tmp/VMwareDnD/VUayTT/char_arr.c' ./my.c)

  或者在widows上,滑鼠右鍵點選複製,再轉到ubuntu上的終端上點選 右鍵---> paste filenames 也會有一個路徑,同樣

  在前面加上 mv 移動到當前; ( mv '/tmp/VMwareDnD/VUayTT/char_arr.c' ./)

(2)、建立共享資料夾

  虛擬機器 -> 設定 -> 選項 -> 共享資料夾 -> 總是啟用 ->選擇一個windows中的一個資料夾作為共享資料夾

  終端訪問: cd /mnt/hgfs/myshare

  共享資料夾設定失敗解決問題:屬性,設定相容性;虛擬機器關鍵。

1.8、圖形介面配置配網

1.8.1、編輯 --> 網路編輯器 --> 更改設定 --> 橋接模式 -->選擇對應網絡卡 -->

虛擬機器 --> 設定 --> 橋接模式。

網路圖示:	-->	edit conections --> 自動 / 靜態
ip:192.168.9.123
子網掩碼:255.255.255.0
閘道器: 192.168.9.1 相關命令: ifconfig 檢視當前ip地址
ctrl+c 結束當前程序
ping + ip地址 連線某個ip

1.8.2、apt 需要外網

軟體源:

   /ect/apt/sources.list

下載的路徑:

   /var/cache/apt/archives/

更新源:

   sudo apt-get update

下載一個軟體:

   sudo apt install 軟體名:

解除安裝:

   sudo apt-get remove 軟體名

清空:

   sudo apt-get clean 軟體名

下載原始碼:

   sudo apt-get source 軟體名

1.9、檔案的壓縮和歸檔

1.9.1、壓縮

針對的是檔案
實質:
把檔案裡的tab/空格等壓縮。
壓縮的時候,原檔案就沒有了,生成了壓縮檔案;
解壓的時候壓縮檔案也變成了原檔案; 速率 大小
.gz: 最慢 最小
gzip 1.c --> 1.c.gz
.bz2: 次之 次之
bzip2 1.c --> 1.c.bgz2
.xz 最快 最大
xz 1.c --> 1.c.xz

1.9.2、解壓

gunzip 1.c.gz 	-->	1.c
bunzip 1.c.bz2 --> 1.c
unxz 1.c.xz --> 1.c

1.9.3、歸檔

歸檔:針對的是一個目錄	“把一個目錄變成一個檔案”
歸檔的時候原始檔依舊存在,生成一個新的歸檔檔案。
釋放的時候,壓縮檔案也存在。 tar 引數 歸檔的檔案 目錄
c 建立歸檔
v 顯示過程
f 後面接檔案
x 釋放後歸檔的檔案還在 z: 壓縮成gzip
j: 壓縮成bzip2
J: 壓縮成xz
eg:壓縮
tar -cvf test.tar test --> test.tar
釋放:
tar -xvf test.tar --> test

1.9.4、壓縮的實質就是歸檔並壓縮

壓縮:
tar - vzcf day1.tar.tar.gz day1 --> day1.tar.gz
解壓:
tar - xzvf day1.tar.tar.gz 萬能解壓:
tar -xvf test.tar.* (* 代表各種格式的壓縮包)。

1.10、檔案相關的內容

1.10.1、vi 三種模式

新建檔案 vi toch

(1)、命令列模式

複製:nyy
貼上:p
剪下:ndd
撤銷:u
返向撤銷:Ctrl + r 查詢:
/string 向下查詢n 向上查詢N
/^string 查詢以string開頭的字串
去游標移到到結尾: G
游標移到到開頭: g
調整格式:gg=G

(2)、插入模式

a 	/	i 	/	b

(3)、底行模式

w
q
wq
q!
wq!
x
:num 去到某一行
srtnumer:設定行號
vsp
替換:
.當前
$最後
g所有
%全文
s/str1/sre2/g 替換 範圍:s/str1/sre2/g
.,$ s/str1/sre2/g
% s/str1/sre2/g
塊複製:
: 1,3 y --> 複製 1~3行

1.10.2、檢視檔案

cat head tail 	nore less(不要)
cat 檔名 //檢視檔案
cat -n 檔名 //連同行號一起檢視 head -n 檔名 //檢視前n行
head -5 檔名 //檢視前5行 tail -n 檔名 //檢視後n行
tail -1 檔名 //檢視最後1行

1.10.3、> 重定向

cat 1.c > 2.c	//把1.c裡面的內容放到2.c裡面,相當於複製

diff	比較一個檔案一不一樣,若沒有輸出內容,檔案內容就一樣;

>>	追加
cat 1.c >> 2.c //把1.c裡面的內容追加到2.c | 管道:把前面的結果作為後面的輸入。
“|”是管道命令操作符,簡稱管道符。
利用Linux所提供的管道符“|”將兩個命令隔開,管道符左邊命令的輸出就會作為管道符右邊命令的輸入。
連續使用管道意味著第一個命令的輸出會作為 第二個命令的輸入,第二個命令的輸出又會作為第三個命令的輸入,依此類推。 練習:把一個檔案的第5行輸出到終端上。

head -5 /etc/passwd > 1.c
tail -l 1.c

head -5 /etc/passwd | tail -l

1.10.4、grep 搜尋

grep “string” 引數 檔案
引數:
-n 行號
-R 遞迴搜尋
-i 不區分大小寫
-w 精確查詢,字串前後如果有內容就查詢不到; grep "include" -n 4.linux_高階進階.c

1.11、find

find 路徑 -name 檔名

1.12、cut

cut -d : -f 1,2 filename
/etc/passwd farsight: x :1000:1000:ubuntu,,,: /home/farsight: /bin/bash
使用者名稱 密碼 uid gid 描述 主目錄
練習:
查一下當前使用者
使用者名稱:UID:GID
head -34 /etc/passwd | tail -1 | cut -d : -f 1,3,4
查一下當前使用者行號
cat /etc/passwd | grep "farsight" -n | cut -d : -f 1

1.13、修改檔案的許可權、使用者、組。

ls -l

	-rw-rw-r--    1    farsight farsight 18672  6月 15 08:48 4.linux_高階進階.c
許可權 連結數 使用者 組
-:
檔案的型別 bcd-lsp
rw-:使用者的許可權 u
rw-:組的許可權 g
r--:其他許可權 o
所有許可權: ugo 或者 a
ls -l 列出屬性
drwxr-xr-x
一個10個字元。第一個字元表示檔案型別,後面9個字元表示檔案許可權。
rwx:r(可讀)、w(可寫)、x(可執行)。
第一組:表示檔案屬主許可權。
第二組:表示屬主所在的組使用者的許可權。
第三組:表示其他使用者的許可權。
r:4	w:2	x:1		最高許可權:777
r 可讀 4
w 可寫 2
x 可執行 1
- 無許可權 0
有了這個編碼規則,則drwxr-xr-x 編碼後為755
三個為一組: 7 5 5

(1)修改許可權:

第一種修改許可權的方法		***
要把 drwxr--r-- 則對應的編碼為744
修改命令:chmod 744 檔名
第二種修改許可權的方法:
在原來的許可權基礎上修改,即增加或減少某許可權。
三個組使用者的編碼依次為:屬主u 屬主所在的組g 其他使用者o
如屬主增加可執行許可權 chmod u+x 檔名
其他使用者增加可寫許可權 chmod o+w 檔名
屬主所在組使用者去掉可執行許可權 chmod g+x 檔名 chmod 777 2.c 賦最高許可權
ls -l 2.c
-rwxrwxrwx 1 farsight farsight 431 6月 16 09:24 2.c
chmod u-x 2.c
ls -l 2.c
-rw-rwxrwx 1 farsight farsight 431 6月 16 09:24 2.c
chmod g-x 2.c
ls -l 2.c
-rw-rw-rwx 1 farsight farsight 431 6月 16 09:24 2.c
chmod o-w-x 2.c
ls -l 2.c
-rw-rw-r-- 1 farsight farsight 431 6月 16 09:24 2.c

(2)修改使用者:

chown
sudo chown 使用者名稱 檔案 修改檔案所屬的使用者
sudo chown 使用者名稱:組名 修改檔案使用者和組
chgrp
sudo chgrp root 2.c 修改檔案的組

1.14、軟連結與硬連結

1.14.1、軟連結:相當於windows的快捷方式

建立軟連線檔案:ln -s 原始檔名 符號連線檔名
reg:ln -s src.c linker.c linker.c就是src.c的一個符號連線檔案 ln -s 原始檔 連結檔案
ln -s a.out app
結論:
(1)app 相當於a.out 的快捷方式;
(2)app 是一個連結檔案, a.out 是普通檔案;
(3)a.out 的連結數不變;
(4)把原始檔刪除或者移動到其他路徑,連結檔案就不可以用了;
(5) 用絕對路徑建立軟連結,把連結檔案移動到其他路徑是可以用的;
eg:
ls -n /home/farsight/210501/day1/day1/a.out app ls -l app
lrwxrwxrwx 1 farsight farsight 37 6月 16 14:05 app -> /home/farsight/210501/day1/day1/a.out

1.14.2、硬連線:對檔案起別名

ln 原始檔名 連線檔案
硬連線實際上和原始檔在硬碟中是同一個東西,效果類似於硬碟上的一個檔案。 結論:
(1)連結數變了
(2)兩個檔案的iNode號是一樣的
(3)硬連結的檔案可有移動1到其他路徑下使用
(4)硬連結檔案是一個普通檔案

1.15、萬用字元

* :	匹配所有字元
? : 匹配一個字元 []:
[字元1字元2] 匹配字元1和字元2中的任意一個字元,不能同時匹配兩個字元;[1234] == [1,2,3,4]
ls name[12].c
[字元1 - 字元2] 匹配到從字元1 至 字元2 的所有字元
ls name[A-F].c
如果出問題,清除本地化設定
export LC_ALL = C
還原:
unset LC_ALL {}:touch name{1,2,3,4,5}.c 同時建立多個檔案;

1.16、程序

程式的一次執行過程

ps

ps -aux

ps -aux | grep a.out 查詢a.out這個程序

top 動態檢測程序

kill 4797 //kill 程序號 --> 殺死一個程序

1.17、man 查詢函式、庫函式、命令的用法

man -a 		查詢所有
man 1 ls 1.表示查詢的是Linux命令
man 2 xx 2.表示查詢的是Linux api 系統呼叫
man 3 xx 3.表示查詢的是Linux庫函式

1.18、使用者管理

1.18.1、新增使用者

adduser	使用者名稱
/etc/skel 模板檔案
/etc/passwd 使用者資訊
/etc/group 組的資訊

1.18.2、切換使用者

su 使用者名稱
新使用者用不了sudo
解決:
sudo su root //進入root使用者
chmod u+w /etc/sudoers //修改可執行許可權
sudo vi /etc/sudoers //進入許可權為普通使用者修改
新增:
test ALL = (ALL:ALL) ALL //新增普通使用者
chmod u-w /etc/sudoers //把許可權修改回來

1.18.3、刪除使用者

deluser 使用者名稱

1.18.4、關機和重啟

sudo shutdown -h now		立即關機
sudo shutdown -h 16:00 關機
init 0 關機
sudo shutdown -r now 立即重啟
sudo reboot 重啟

1.18.5、usermod

sudo usermod -aG farsight mytest  把mytest這個使用者追加到farsight這個組裡;
用 id 使用者名稱 可以看到效果: id mytest sudo usermod -c hello mytest 把mytest這個使用者的第五個描述修改為hello; sudo usermod -d /home/farsight mytest 把mytest 這個使用者的家目錄改為 /home/farsiht sudo usermod -g farsight mytest 把mytest這個使用者的組改為 farsight
id mytest
uid=1003(mytest) gid=1000(farsight) groups=1000(farsight)
sudo usermod -l test1 mytest 把mytest這個使用者名稱改為test1 注意:不要在使用者登入的時候修改資訊。若果還是報錯,把當前終端退出, (exit)

1.18.6、修改密碼

sudo passwd user1	為名為user的使用者設定密碼

1.19、磁碟相關的命令

1.19.1、檢視磁碟的相關資訊

sudo fdisk -l

  /dev/sda: 系統盤 --> Disk /dev/sda: 21.5 GB, 21474836480 bytes

1.19.2、檢視磁碟分割槽資訊

df -h

1.19.3、將U盤掛載在Ubuntu上: USB/2.0 3.0

虛擬機器 -> 可移動裝置 -> flush disk

在家目錄建立:mkdir ~/udisk

掛載: sudo mount /dev/sdb1 ~/udisk

就可以進入到udisk中訪問u盤:

取消掛載:

   sudo umout /dev/sda1 ~/udisk

1.20、網路知識

域名解析伺服器:
8.8.8.8
114.114.114.114.114
自己的ip地址: 192.168.6.81 sudo vi /etc/network/interfaces 開啟配置檔案
auto lo
iface lo inet loopback auto eth0
iface eth0 inet dhcp //兩個字串之間是tab鍵的距離 sudo /etc/init.d/networking restart 讓配置檔案生效 如果沒有圖示:
sudo vi /etc/NetworkManager/NetworkManager.conf 2 [main]
3 plugins=ifupdown,keyfile
4 dns=dnsmasq
5
6 no-auto-default=00:0C:29:A4:5E:47,00:0C:29:85:E8:39,00:0C:29:02:7A:D6,
7
8 [ifupdown]
9 managed=true //把false 改成 true

1.21、環境變數

env		檢視環境變數
檢視單個環境變數:
echo $PATH
PATH 它是用來儲存系統可執行程式路徑的變數
/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/farsight/OpenWrt-SDK-ar71xx-for-linux-i686-gcc-4.8-linaro_uClibc-0.9.33.2/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin:/home/farsight/gcc-4.6.4/bin
echo $HOME 主目錄 如何使得a.out可以直接使用:
①只針對當前終端有效。
export PATH=${PATH}:./
export 匯入環境變數
PATH 環境變數
= 賦值
${PATH} 引用環境變數path 裡的內容
: 起到分割的作用
./ 把當前路徑加上去
②在當前使用者下生效
vi .bashrc 開啟
在最後的位置新增:
//export PATH=${PATH}:./
//export PATH=${PATH}:./home/farsight 在主目錄下生效
③在所有檔案下省效
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/game
s:/home/farsight/OpenWrt-SDK-ar71xx-for-linux-i686-gcc-4.8-linaro_uClibc-0.9.33.2/staging_dir/
toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin:/home/farsight"
source /etc/environment //讓過程更改的環境變數生效
或者 sudo reboot 重啟;

二、shell

2.1、實質:shell命令的有序集合

把shell指令碼放在一個檔案中,那麼這個檔案就是shell指令碼

2.2、shell命令列直譯器

sh

csh

ksh

bash --> ubuntu

2.3、shell指令碼

2.3.1、字尾為.sh

eg:(1)在家目錄建立一個目錄 mydir
(2)把 /etc/passwd 和 /etc/groff 複製到mydir
(3)壓縮並歸檔位mydir.tar.gz
eg:#!/bin/bash
cd
mkdir mydir
cp /etc/passwd ./mydir
cp -a /etc/groff ./mydir
tar -cvzf mydir.tar.gz mydir

2.3.2、shell指令碼為直譯器語言,不需要編譯

2.3.3、執行

(1)建立指令碼 :vi demo.sh

在開頭加上:#!/bin/bash

(2)修改許可權:

chmod 777 demo.sh 修改為可執行的檔案

(3)執行指令碼

./demo.sh
bash demo.sh
source demo.sh
三種執行方式的區別:
(1)./執行的時候需要賦上可執行的許可權,後兩者可以直接執行;
(2)./和bash在執行的時候會新開一個字終端,最後把結果直接返回給終端。
(3)source 執行的時候在當前終端執行,一般用來讓某個指令碼生效;

2.4、shell指令碼的變數

2.4.1、變數的定義

沒有資料型別,不需要提前定義直接使用;

給變數賦值的時候等號左右不能有空格

每一行語句不需要加‘;’

變數名見名知意;

賦值給變數都預設為字串;

2.4.2、變數的引用

$var

$(var)

2.4.3、在給吧變數賦值的時候可以加雙引號和單引號,也可以不加:

單引號和雙引號的區別:
單引號和雙引號內都可以加空格;
單引號裡面不能引用變數
給變數賦值的時候不需要加上 $
var=10
var=11; // 再次賦值 eg:#!/bin/bash
a=22
b="open book"
c="$a open" echo $a
echo $b
echo $c
輸出:
22
open book
22 open 單行註釋: #
多行註釋: :<<EOF
被註釋的內容
EOF
或者
:<<!
被註釋的內容
!

2.4.4、刪除變數:變數被刪除後不能再次使用

unset var1
eg:myur1="www.baidu.com"
unset myur1
echo $myur1
輸出:
//空格

2.4.5、命令置換

把命令賦值給了一個變數
var=`ls`
或者
var=$(ls) //不輸出不會執行
eg:
var=`ls`
var1=$(ls)
echo $var
echo $var1

2.4.6、位置變數

$0	$1	$2	$3...
$# $* $@ $$ $0 用./ 和 bash執行 代表shell指令碼檔名,用source執行代表bash
$1 shell指令碼檔名後面第一個引數
$2 shell指令碼檔案後面第二個引數 $* 和 $@ 表示shell檔名後面的所有引數,不包含檔名
$# 表示shell檔名後面所有的引數,不包含檔名
$$ 表示程序號
練習:
用一個變數1儲存PATH, 變數2儲存HOME, ----> 交換;
var1=${PATH}
var2=${HOME}
echo var1: $var1
echo var2: $var2
var3=$var1
var1=$var2
var2=$var3
echo var1: $var1
echo var2: $var2

2.4.7、shell處理字串

(1)、字串的複製

str=hello
strl=$str
eg:#!/bin/bash
str=hello
str1=$str echo $str
echo $str1
輸出: hello
hello

(2)、字串的連線

str=hello
str2="$str hello"
eg:#!/bin/bash
str=hello
str1=$str
str2="$str1 hello"
echo $str
echo $str1
echo $str2
輸出: hello
hello
hello hello

(3)、字串的長度

string=“hdsjf”
echo $(#string)

(4)、字串的提取

	strstr()      str1[] = "hello world"  str2[]= "world"

① ${str:start:len}
從左邊的0開始數,數到start的位置,從這個位置輸出len個字元;
eg:str="www.baidu.com"
echo ${str:3:4}
結果:
.bai
② ${str:start}
從左邊的0開始數,數到start的位置,從這個位置開始輸出直到最後一個字元結束;
eg:str="www.baidu.com"
echo ${str:3}
結果:
.baidu.com
③ ${str:0-start:len}
從右邊的0開始數,數到start的位置,從這個位置的後一個字元開始輸出len個字元;
eg:str="www.baidu.com"
echo ${str:0-4:3}
結果:
.co
④ ${str:0-start}
從右邊的0開始數,數到start的位置,從這個位置的後一個字元輸出直到最後一個字元結束;
eg:str="www.baidu.com"
echo ${str:0-7}
結果:
idu.com ⑤ ${str#*sub} 從左邊開始數,第一遇到 sub , 輸出它後面的所有內容;
eg: str="www.baidu.com www.baidu.com www.baidu.com" 針對於:⑤-⑧
echo ${str#*bai}
結果:du.com www.baidu.com www.baidu.com ⑥ ${str##*sub} 從左邊開始數,最後一次遇到 sub , 輸出它後面的所有內容;
eg:str="www.baidu.com www.baidu.com www.baidu.com"
echo ${str##*bai}
結果
du.com
⑦${str%sub*} 從右邊開始數,第一次遇到 sub ,輸出它前面的所有內容;
~ eg:str="www.baidu.com www.baidu.com www.baidu.com"
echo ${str%bai*}
結果:
www.baidu.com www.baidu.com www. ⑧${str%%sub*} 從右邊開始數, 最後一次遇到 sub ,輸出它前面的所有內容;
eg:str="www.baidu.com www.baidu.com www.baidu.com"
echo ${str%%bai*}
結果:
www.

2.5、shell 處理陣列

陣列定義:

arr=(1 2 3 4)依次對陣列賦值;陣列的下標也從0開始數的。

arr=([0]=aaa [2]=bbb) 對數組裡面的部分元素

注意:沒有被賦值到的地方就為空(不是零)。

2.5.1、陣列的引用:陣列的下標也是從0開始數的

${陣列名字[下標]}

2.5.2、引用整個陣列

${arr[*]} 或者 ${arr[@]}

2.5.3、求陣列元素的長度

echo ${#arr1[0]} //arr1[0]整個陣列的長度

2.5.4、求整個數組裡面被賦值的元素的個數

echo ${#arr1[@]}

2.5.5、清空陣列

unset arr[0] 清空這個元素

unset arr[*] 清空整個陣列

2.5.6、arr=(${arr[*]} "how are you") 在陣列後面新增內容

arr=("hello" ${arr[*]}) 在陣列前加內容

eg:
#!/bin/bash
arr=(1 2 3 4)
echo ${arr[0]}
echo ${arr[2]}
echo ${arr[*]}
echo ${arr[@]}
arr[2]=20;
arr[5]=10
echo ${arr[5]}
echo ---------------
arr1=([0]=hello [3]=56 [6]=bbb)
echo arr1:${arr1[0]}
echo arr3:${arr1[3]}
echo arr6:${arr1[6]}
echo arr2:${arr1[2]} echo ${#arr1[0]}
echo ${#arr1[@]} unset arr1[0]
echo ${arr1[0]}
echo ................
unset arr1[*]
echo ${arr1[*]} 結果: 1
3
1 2 3 4
1 2 3 4
10
---------------
arr1:hello
arr3:56
arr6:bbb
arr2:
5
3 ................

2.6、read 從終端上輸入

read 變數

2.6.1、如果輸入兩個變數

用法:read var1 var2
var1 和 var2 的複製通過第一個空格來分割,
//空格前面的內容賦值給var1,後面的所有內容賦值給var2 單次輸入
eg:#!/bin/bash
echo "please enter a var ->:"
read var
echo var:$var 兩次輸入: // 兩次輸入即可輸入帶空格的字串;
read var1
read var2

2.6.2、read -p "提示" var //輸入提示性的東西

2.6.3、read -a arr (陣列名) //輸入一個數組

read -p "請輸入一個數組" -a arr // read -a arr

echo ${arr[*]}

2.6.4、read -n num var

read -n 5 var //輸入5個字元以後直接退出

2.6.5、read -t 秒鐘 var //在規定的時間內輸入,超時自動退出

2.6.6、read -s var //輸入的沒有回顯

eg:
read -p "請輸入使用者名稱" var1
read -p "請輸入密碼" -s var2
echo var1 = $var1
echo var2 = $var2 結果: 請輸入使用者名稱farsight
請輸入密碼
var1 = farsight
var2 = 1

2.7、shell輸入

echo $var
echo hello
echo "hello"
echo 'hello'
echo -n "hello world" 不換行

2.8、shell的運算

+	-	*	/	%
> <
++ --
** 冪運算
+= -= *= /=
&& || !
> < == =(shell也可以用來做等於)
& | ~ ^

2.8.1、(( ))

((表示式))

((表示式1,表示式2,表示式3)) 執行最後一個表示式的結果

取值:$((表示式))

(1)表示式裡面取變數的時候可以加$,也可以不加;
(2)可以運算結果賦值給一個變數
ret=$((表示式))
(3)可以支援自加或者自減運算
((var1++))
echo $var1
(4)運算的時候可以加空格
(5)$? 執行成功,返回上一次執行過程(上一次邏輯為真返回0,上一次邏輯為假返回1)
(6)支援整數運算,不支援字串運用
eg:#/bin/bash
var1=10
var2=20
var3=$((var1+var2))
echo var1+var2 = $var3
var3=$(($var1 + $var2))
echo var1+var2 = $var3 ret=$(($var1+$var2))
echo ret = $ret ((var1++))
echo var1=$var1 ((mm=3**2))
echo mm=$mm echo $((mm=3**2)) #複雜運算
echo $((var1 > var2))
echo $((var1 < var2))
echo $? #返回上一次執行結果
((var2 > var1))
echo $? #shell 邏輯為真返回0,為假返回1 輸出: var1+var2 = 30
var1+var2 = 30
ret = 30
var1=11
mm=9
9
0
1
0
0

2.8.2、$ [ ]

ret=$[表示式]

ret=$[表示式1,表示式2,表示式3,......]

(1)需要把執行結果賦值給一個變數
(2)可以支援自加,自加的時候不能加$
(3)在運算的時候變數也可以加$,也可以不加
(4)如果有多個表示式則執行右邊的結果
(5)支援整數運算,不支援字串運用
eg:#/bin/bash
var1=10
var2=20 ret=$[var1++]
ret=$[$var1+$var2]
echo $ret
echo $var1 ret=$[1,2,3,3+4]
echo $ret ret=$var
echo $ret
ret=$[var+1]
echo $ret ret=$[var * 3]
echo $ret
ret=$[var / 3]
echo $ret
輸出: 31
11
7 1
0
0

2.8.3、expr

(1)支援整數運算並且支援字串的相關操作
(2)expr 可以直接輸出結果
(3)expr 的運算需要加空格
(4)expr 的運算,變數的引用需要加$
(5)expr 在賦值的時候需要命令置換
①var=`expr $var1 + $var2`
②var=$(expr $var1 + $var2)
(6)expr 不支援自加
(7)expr 不支援冪運算
(8)expr 識別不了*,需要加\字元
\*
\>
\<
\(\) 不加預設為陣列
eg:#/bin/bash
var1=10
var2=20 expr var1+var2
expr $var1+$var2
expr $var1 + $var2 var=`expr $var1 + $var2`
echo $var
var=$(expr $var1 + $var2)
echo $var expr $var1++ #不支援自加
expr ++$var1
expr $var1 expr mm=3**2
echo $mm ret=$(expr $mm=3**2)
echo ret = $ret expr $var1 \* $var2 輸出: var1+var2
10+20
30
30
30
10++
++10
10
mm=3**2
ret = =3**2
200

2.8.4、字串操作

匹配字串:

expr match $var "sub" //從開頭匹配字串,有多少個字元相同就返回多少的數

eg:str="hellowoed"
#str="hell owoed" #error 不能加空格
expr match $str "hel"
expr match $str he
expr match $str "wor"
expr match $str w
expr length $str #求字串長度 輸出: 3
2
0
0
9

2.9、if else

if [條件]
then
shell語句1
else
shell語句2
fi if [條件]
then
shell語句1
elif [條件]
shell語句2
then
shell語句3
else
shell語句4
fi 判斷:
①[表示式] --> 表達的前後必須加空格\[\]前後也要加空格;
②test 前後加空格

2.9.1、數字大小判斷

-eg 	等於
-ne 不等於
-gt 大於
-ge 大於等於
-lt 小於
-le 小於等於

2.9.2、邏輯的判斷

&&	-->		-a
|| --> -o
! --> !
練習:輸入一個成績,
[90-100] A
[70-90) B
[60-70) C
[0-60] D
eg:#/bin/bash
read -p "please enter a sore:>" num
if test $num -gt 100 -o $num -lt 0
then
echo "error ---> [0-100]"
exit 1
fi if test $num -ge 90 -a $num -le 100
then
echo A
elif test $num -ge 70 -a $num -lt 90
then
echo B
elif test $num -ge 60 -a $num -lt 70
then
echo C
else
echo D
fi
#bash if_score.sh
#. if_score.sh # ./if_score.sh
source if_score.sh exit num
num == 1 非正常退出
num == 0 正常退出 shell檔案中:再次呼叫指令碼
#bash if_score.sh
#. if_score.sh # ./if_score.sh
source if_score.sh

2.9.3、字串的判斷

-n 判斷字串非空

-z 判斷字串為空

= 判斷字串相等

!= 判斷字串不等

> 比較字串的大小

<

if test -n "$var1" -a -n "$var2"

1引數放前面

2變數的引用需要加" ",不然輸入空的時候會報錯。

練習:從終端輸入兩個字串,判斷是否為空,如果不為空則比較大小;
eg:#!/bin/bash
read var1
read var2 if test -n $var1 -a -n $var2
then
if test $var1 \> $var2
then
echo "$var1 > $var2"
else
echo "$var1 < $var2"
fi
else
echo "不空"
fi

2.9.4、檔案判斷

bsp-lcd

-b 判斷檔案是否存在,並且判斷是否為塊裝置檔案

-s 判斷檔案是否存在,並且判斷是否為套接字檔案

-p 判斷檔案是否存在,並且判斷是否為管道檔案

-f 判斷檔案是否存在,並且判斷是否為普通檔案

-c 判斷檔案是否存在,並且判斷是否為字元裝置檔案

-L 判斷檔案是否存在,並且判斷是否為連結檔案

-d 判斷檔案是否存在,並且判斷是否為目錄檔案

-e 判斷檔案是否存在,

-s 判斷檔案是否存在,且判斷檔案是否為空,檔案大小大於0,返回真值。

練習:輸入一個檔名字。判斷是普通檔案還是目錄檔案
eg:#!/bin/bash
file="/home/farsight/HuaQing_vision/qrs210501/2.linux_c高階/day4/" #read -p "請輸入一個檔名:" file if [ -f $file ]
then
echo "普通檔案"
elif [ -d $file ]
then
echo "目錄檔案"
else
echo "檔案不存在"
fi

2.9.5、判斷檔案的許可權

-w 	判斷寫許可權
-r 判斷有沒有讀許可權
-x 判斷有沒有執行許可權

2.9.6、判斷檔案的時間戳

-nt 比較兩個檔案的時間戳更新

-ot 比較兩個檔案的時間戳更舊

練習:輸入一個檔名,判斷是否具有寫許可權,如果有,那麼將helloworld寫在這個檔案裡,如果沒有新增許可權再寫進去;
eg:#!/bin/bash
read -p "請輸入一個檔名" filename
if test -w $filename
then
echo "helloworld" > $filename
else
echo "沒有寫許可權"
chmod u+w $filename
echo "helloworld" > $filename
練習:輸入兩個檔名,判斷時戳
eg:#!/bin/bash
read -p "enter file1>:" file1
read -p "enter file2>:" file2 if test -e $file1 -a -e $file2
then
if test $file1 -nt $file2
then
cat $file1 > $file2
else
cat $file2 > $file1
fi
else
echo "檔案不存在"
fi

2.9.7、case 表示式 in

引數1
shell 語句1
;;
引數2
shell 語句2
;;
引數3
shell 語句3
;;
引數4
shell 語句4
;;
esac
eg:echo '輸入 1 到 4 之間的數字:'
echo '你輸入的數字為:'
read aNum
case $aNum in
1) echo '你選擇了 1'
;;
2) echo '你選擇了 2'
;;
3) echo '你選擇了 3'
;;
4) echo '你選擇了 4'
;;
*) echo '你沒有輸入 1 到 4 之間的數字'
;;
esac
*	-->	所有
練習:模擬一個軟體的下載的過程
#!/bin/bash
read -p "enter num :" app
read -p "請選擇命令[Y/N/Q]" cmd case $cmd in
Y|YES|yes|)
echo "$app 正在下載....."
;;
N|NO|no|)
echo "取消下載 $app....."
;;
Q|quit|q|)
exit 0
esac

2.10、迴圈: while [條件]

		do
語句
done 無限迴圈: while true
do
echo "***"
done
練習:寫一個加法計算器, 輸入一個值就一直累加,輸入 exit 退出;
eg:#!/bin/bash
while read -p "請輸入一個整數或者輸入q 退出:" num
do
if test $num = q
then
exit 0
else
((sum+=$num))
echo ret: $sum
fi
done
用法1:
for((表示式1;表示式2;表示式3))
do
shell語句塊
用法2:
for var in 單詞列表
do
shlle語句
done 單詞列表:
1)如果是散亂的列表,列表中用空格作為分割;
2)順序的列表: {start..end}
eg:
for var int {1..100}

2.11、函式

函式的一般形式:

function 函式名()

{

}

(1)shell函式沒有形式引數,沒有返回值(也可以有)
(2)函式中的變數為全域性變數
(3)將命令執行的結果作為作為單詞列表
(4)for var in `ls`
1.function 代表這是一個函式
(5)使用local 修飾是區域性變數
函式的呼叫:
函式名
函式名:argv[1] argv[2] ...
|
|
|
$0 $1 $2
eg:#!/bin/bash
function add(){
sum=$((10+20))
}
add
echo $sum function add1(){
sum=$(($1+$2))
}
add1 50 60
echo $sum function add2(){
local sum=$(($1+$2))
return $sum
}
add2 $1 $2
echo $?

三、c高階

3.1、c語言的本質

操作虛擬的記憶體

3.2、c語言中如何分配記憶體

3.2.1、資料型別

(1)、基本資料型別

int float char short long double

(2)、使用者自定義的資料型別

陣列: 在記憶體中連續開闢相同資料型別的空間

結構體:描述一個物件,物件具有很多的屬性 

		關鍵字: struct

		結構體的資料型別 == 關鍵字+結構體名

		結構體指標 (01struct.c)
結構體陣列 (02struct_arr.c) 位元組對齊:32位系統下,4位元組對齊, 會畫圖 共用體:類似於結構體 關鍵字: union
特性1:共用體中每個成員都共用同一個記憶體起始地址,共用體佔用的記憶體等於最大的成員佔用的記憶體
特性2:如果對新的成員賦值,會把原來的成員的值覆蓋掉

(3)、指標型別

(1)基本用法
& : 取出變數的地址
* : 取出地址的值 05pointer.c (2)特點 : 指標是有粗細的 (3)陣列指標(行指標) 07shuzu_zhizhen.c (4)指標陣列 08zhizhen_shuzu.c (5)二級指標 09erji_pointer.c (6)不定型別的指標 : void * pthread_create();

3.2.2、程式設計師手動開闢記憶體空間

malloc free

#include <stdio.h>
#include <stdlib.h> //malloc包含標頭檔案
int main(void)
{
// 需要一個1000個int型別元素的陣列 // 第一步:申請和繫結
int *p = (int *)malloc(1000*sizeof(int)); // 第二步:檢驗分配是否成功
if (NULL == p)
{
printf("malloc error.\n");
return -1;
} // 第三步:使用申請到的記憶體
//p = NULL;
//p = &a; // 如果在free之前給p另外賦值,那麼malloc申請的那段記憶體就丟失掉了
// malloc後p和返回的記憶體相繫結,p是那段記憶體在當前程序的唯一聯絡人
// 如果p沒有free之前就丟了,那麼這段記憶體就永遠丟了。丟了的概念就是
// 在作業系統的堆管理器中這段記憶體是當前程序拿著的,但是你也用不了
// 所以你想申請新的記憶體來替換使用,這就叫程式“吃記憶體”,學名叫記憶體洩漏
//申請後使用
*(p+0) = 1;
*(p+1) = 2;
printf("*(p+0) = %d.\n", *(p+0));
printf("*(p+1) = %d.\n", *(p+1)); *(p+222) = 133;
*(p+223) = 222; // 第四步:釋放
free(p);
p = NULL; //釋放之後p指標就沒有指向了;p=NULL,防止野指標 printf("*(p+222) = %d.\n", *(p+222));
printf("*(p+223) = %d.\n", *(p+223)); return 0;
}

3.3、函式

3.3.1、函式形式

返回值 函式名(引數)

{

}

3.3.2、函式傳參

值傳遞

地址傳遞

3.3.3、函式封裝

main.c : 主函式, 函式呼叫

fun.c : 各種方法

fun.h : 函式宣告、結構體

3.3.4、指標函式:返回值是一個地址的函式

3.3.5、函式指標:本質是一個指標,指向一個函式

vi指定複製:shift+滑鼠選擇

3.3.6、函式指標陣列:本質上是一個數組,儲存的是一個函式指標。

3.3.7、遞迴函式:自己呼叫自己。注意必須有終止條件。

3.3.8、回撥函式:點餐, 服務員, 廚師

回撥函式模型

3.4、gcc、gdb

3.4.1、使用gcc對程式碼進行編譯

  • 1>預處理 :

    gcc -E 1.c -o 1.i 預處理:用於將所有標頭檔案以及巨集定義替換成其真正的內容,預處理之後得到的仍然是文字檔案,但檔案體積會大很多。

  • 2>編譯 :

    gcc -S 1.c -o 1.s 生成組合語言原始碼檔案

  • 3>彙編 :

    gcc -c 1.c -o 1.o 將上一步的彙編程式碼轉換成機器碼,二進位制格式

  • 4>連結 :

    gcc 1.c 生成可執行檔案,將多個目標檔案以及所需要的庫檔案(.so等)連結成最終的可執行檔案

3.4.1、使用gdb對程式碼進行除錯

編譯的時候需要新增一個-g的引數

gcc 08malloc.c -g

使用gdb執行程式

gdb a.out

獲取幫助資訊:

(gdb)help

檢視程式碼

l 預設顯示的是前10行

l 可以向下檢視下面的10行

l - 向前顯示10行

新增斷點

b 行號

如何檢視斷點

info b

刪除斷點

delete 斷點號

執行程式碼:

r 執行程式碼,在斷點的位置會停掉

檢視資料

p 變數

watch 變數

單步執行

n 單步執行,當遇到函式時不會顯示函式執行過程

s 單步執行,當遇到函式時顯示函式執行過程

繼續執行

c 沒有錯誤就繼續向下執行,在斷點的位置會停掉

退出除錯:

q 退出

3.5、儲存型別

儲存型別(6種) auto static register extern volatile const

3.5.1、auto: 在定義變數的時候,預設儲存型別為auto。

全域性變數和區域性變數:

#include <stdio.h>

int x=10;
void func(void)
{
printf("x = %d\n",x);
} int main(int argc, const char *argv[])
{
auto int x=5; //作用域 花括號
printf("x = %d\n",x); //5 {
auto int x=7;//作用域 花括號
printf("x = %d\n",x); //7
} printf("x = %d\n",x); //5 func(); //10 return 0;
}

3.5.2、extern :可以用來宣告變數或者函式是在其他檔案中

#include <stdio.h>
extern int a, b;
extern int fun(int , int ); int main()
{
printf("a = %d\n", a);
printf("b = %d\n", b);
printf("a+b = %d\n", fun(a,b));
} #include <stdio.h>
int a = 12, b = 13; #include <stdio.h>
int fun(int a, int b)
{
return a+b;
}

3.5.3、static

(1)、延長變數的生命週期

#include <stdio.h>

void func(void)
{
static int a=1;
static int b;
//如果a沒有被static修飾,預設a在棧上存放,當函式被呼叫的使用分配棧空間,當函式呼叫完,棧就會被釋放了。所有這裡列印的a的值都是2; //如果加上了static修飾,並且static修飾的變數被賦值了,static修飾的變數在靜態區種的.data存放著,在函式執行結束的時候,data段不會被釋放,所以列印的結果是2 3 4 //static修飾的變數如果沒有被初始化,變數在.bss段存放著 a++;
printf("b = %d\n",b);
printf("a = %d\n",a);
} int main(int argc, const char *argv[])
{
func();
func();
func();
return 0;
}

(2)、限定作用域(物件可以是函式,也可以是變數)

static修飾的變數或者函式只能在當前檔案中使用

3.5.4、const :只讀的變數

const int a=10;

a=100; //錯誤的,const修飾的變數不允許修改

(1)、const修飾區域性變數 --> 可以改變值 棧區

(2)、const修飾全域性變數 --> 不能改變值 只讀區

#include <stdio.h>

const int b=500; //只讀區

int main(int argc, const char *argv[])
{
const int a=10; //棧
//a=100; //錯誤的,const修飾的變數不允許修改 int *p=(int *)&a;
*p=100; printf("*p = %d,a = %d\n",*p,a); p=(int *)&b;
*p=123;
printf("*p = %d,b = %d\n",*p,b); return 0;
}

(3)、const修飾指標

#include <stdio.h>

int main(int argc, const char *argv[])
{
int a=100;
int b=234; //第一種
const int *p=&a;
*p=50; //p指向的地址中的內容不能修改
p=&b; //p指向的地址可以修改 //第二種
int const *p=&a;
*p=50; //p指向的地址中的內容不能修改
p=&b; //p指向的地址可以修改 //第三種
int *const p=&a;
*p=50; //p指向的地址中的內容可以修改
p=&b; //p指向的地址不能修改 //第四種
const int *const p=&a;
*p=50; //p指向的地址中的內容不能修改
p=&b; //p指向的地址不能修改 return 0;
}

3.5.5、register :(暫存器)

register int a;

定義的register型別的變數要比不加register的時候執行的速率要快。

問題1:暫存器型別的變數執行的速率快,能不能把所有的變數都定義成暫存器型別的變數?

答案:不能,在晶片內部暫存器是有個數限制的,比如在A53硬體平臺上只有40個暫存器。

問題2:在定義變數的時候const和volatile能不能同時使用?

答案:可以的,只讀的狀態暫存器

3.5.6、volatile:(易變的)

volatile int a;

(1)、編譯器優化 -O3

volatile int *a=&b; //防止編譯器對程式碼進行優化

*a = 110;

*a = 120;

(2)、防止cpu值取資料從快取(cache register)中取

volatile修飾的變數每次都從記憶體中取出

(3)、在開發過程中需要定義變數的時候需要加volatile

   1.在定義硬體地址的時候。(比如:狀態暫存器)

   2.在中斷處理函式中訪問的非自動變數時,需要新增volatile

   3.多個執行緒訪問的同一個變數

例如:向0x80000000地址中寫入0x12345678值

   volatile unsigned int *p=(volatile unsigned int *)0x80000000

   *p=0x12345678;

四、makefile

4.1、什麼是Makefile

一個檔案,對專案進行管理

Makefile可以體現你是否具備大型專案的開發能力

4.2、什麼是make

是一個工程管理器,管理較多的檔案

是一個可執行程式,通過讀取Makefile內容,呼叫編譯器進行編譯工作

(本質工作還是GCC在做)

根據檔案時間戳來編譯檔案(檔案更新時間)

只編譯修改後的檔案,而不用全部編譯,節省時間。

Makefile是make讀入的唯一配置工具

4.3、體驗Makefile

all:  //---標籤
gcc -E test.c -o test.i
gcc test.c -Wall -o test //--要做的事情,前面是一個tab鍵!
clean: //---標籤
rm test.i test 1.make預設執行all標籤下內容
2.make clean 會執行clean標籤後的內容,刪除檔案 all: //---標籤
gcc -E test.c -o test.i
gcc test.c -Wall -o test
.PHONY: //偽指令
clean:
rm test.i test
偽目標:不生成目標檔案的目標為偽目標
.PHONY: 的作用是將clean檔案屬性遮蔽掉,只單純的任務就是一個偽目標

4.4、Makefile的規則

目標:依賴檔案

   操作

out:main.o fun1.o fun2.o
gcc main.o fun1.o fun2.o -o out
main.o:main.c
gcc -c main.c -o main.o
fun1.o:fun1.c
gcc -c fun1.c -o fun1.o
fun2.o:fun2.c
gcc -c fun2.c -o fun2.o

4.5、變數

節省繁複的操作,方便替換

類似shell指令碼中的變數

CC=gcc

$(CC)

CC=arm-linux-gcc 

out:main.o fun1.o fun2.o
$(CC) main.o fun1.o fun2.o -o out
main.o:main.c
$(CC) -c main.c -o main.o
fun1.o:fun1.c
$(CC) -c fun1.c -o fun1.o
fun2.o:fun2.c
$(CC) -c fun2.c -o fun2.o CC 預設值gcc CC = arm-linux-gcc
RM 預設值為rm 刪除命令
CFLAGS 編譯器的引數選項
LDFLAGS 編譯器連結檔案及路徑
APP 檔案最後生成的可執行程式a.out
SRCS 所有的.c檔案
OBJS 依賴檔案 eg:
#編譯時的編譯選項
CFLAGS = -Wall -o2 -g -std=gnu99 -pthread -I./include -DMYDBG
LDFLAGS = -L./lib/x86/ -lcam -L./lib/x86/ -lserial -L./lib/x86/ -ltcp -ljpeg -lpthread #使用者自定義變數,儲存 可執行程式的名字
APP = server #自定義變數,用來儲存某個目錄下的所有 C檔案
SRCS = $(wildcard ./src/*.c) #自定義變數,將某個變數中的所有C檔案,替換成 .o 檔案
OBJS = $(patsubst %.c, %.o,$(SRCS)) CC = gcc
#CC = arm-linux-gcc
all: $(APP) $(APP): $(OBJS)
$(CC) -o $(APP) $^ $(LDFLAGS)
$(RM) $(OBJS) clean:
$(RM) $(OBJS) $(APP)

更多詳情makefile 可參考文件 跟我一起學makefile 百度雲下載連結:https://pan.baidu.com/s/1McHYZuCSGjpOK19UOqLQeQ

跳轉:上一篇、Linux c基礎!

待更新。。。

跳轉:下一篇、資料結構與演算法!

跳轉:下一篇、資料結構與演算法!

跳轉:開頭