~好記性不如爛筆頭,這就是我的筆記~
since 2014.4.3
1、查看進程的環境變量
普通:$cat /proc/1642/environ
換行:$cat /proc/1642/environ | tr '\0' '\n'
tr的命令格式是tr SET1 SET2,凡是在SET1中的字符,都會被替換為SET2中相應位置上的字符。
2、SHELL腳本賦值與等於判斷
賦值:$var=value
相等:$var = value
在賦值時不要留有空格。
3、從進程名字得知進程ID
$ pgrep my_proc
4、當前環境變量
$PATH
記住必須是大寫
輸出BASH路徑:$echo $SHELL
注意不要在*.sh文件里定義名為PATH的變量,否則會導致后面的命令無法執行,因為PATH被更換掉了。
修改環境變量:
export PATH=/home/work/cswuyg/:$PATH
export命令可以打印出所有的環境變量信息
5、查看文件
alias ll='ls -l' ; ll等同於ls -l
查看隱藏文件:
隱藏屬性的文件的文件名以“點”開頭
ls -al
查看普通文件:
ls -l
按時間排序:
ll -t; ll -rt (時間從小到大)
查看文件名含有某些字符的文件:
ll *active*03-24*.origin -rt
按文件大小排序:
ls -l |sort -n
6、bash中的雙引號和單引號的不同
shell腳本:
count=9
fruit=apple
echo "we hava $count${fruit}s"
其中fruit是字符串變量, 如果雙引號換成單引號那就導致fruit輸出錯誤。
加上大括號{}是因為后面有其他字符串,需要做隔開。
shell中的單引號、雙引號、反引號:
單引號:所有轉義符全部關閉,完整的反應括號中的內容
雙引號:部分轉義符關閉,但某些則保留(如:$ )
反引號:反引號內作為一個系統命令並執行
7、shell腳本中的括號
兩層小括號:
((exp)),兩層括號表明里面的是整數型運算,如:
- a=10;((a++));echo $a
- for ((i=0;i<5;i++));do echo $i;done
中括號:
中括號等同於test;也可以用來引用數組元素。
- test功能舉例:
a=10;if [ $a = '10' ];then echo 'a==10';fi
- 數組元素引用舉例:
array[1]=world
array[0]=hello
for k in ${!array[@]};do echo ${array[${k}]};done
雙中括號[[]]也有test的功能,而且比單個中括號更通用。
大括號:
可以:擴展;代碼塊;替換;匹配;取字符
- 擴展舉例:
touch {a,b}.txt : 創建a.txt和b.txt
echo {0..4} : 輸出0 1 2 3 4
- 代碼塊舉例:
{ a=10;b=20;};echo $a
- 字符串替換舉例:
A=${c:-NULL};echo $A :如果c變量不存在,則A被賦值為NULL,否則就是c變量的值。
A=${c:+NULL};echo $A : 如果c變量存在,則A被賦值為NULL,否則就是c變量原來的值(不存在)。
上例子中的NULL可以換成其它的字符串
- 字符串匹配舉例:
temp=${file%.*} #右到左匹配,留下不匹配的
log_date=${temp##*_} #左到右貪婪匹配,留下不匹配的
兩個%或者兩個#都表示貪婪匹配。
- 取字符
input=0123;echo ${input:0:3} 輸出: 012
8、給予腳本可執行屬性
$ chmod a+x script.sh
在執行的時候必須帶上:./ 指明是在當前目錄
注意shell腳本的開頭行需要指定腳本執行程序: #!/bin/bash
9、shell腳本中的條件語句
if [ $UID -ne 0 ]
then echo xxx
else echo yyy
fi
注意,"["后邊有空格,"]"前面有空格。
數字比較:數字小於:-lt;數字等於:-eq;數字大於:-gt
判斷一個文件是否存在
if [ -f $FILEPATH ]
then
xxxx
fi
if [ $UU_FILE_NUM -gt 0 ] && [ ! -f ${UU_DEST} ] # 並列條件語句
...
判斷目錄是否存在:
if [ ! -d "glog_log" ]
then
echo "create"
mkdir glog_log
fi
判斷某一類文件是否存在:
思路,獲取這一類文件的文件個數,判斷是否大於0
UU_ORG=*active*
UU_FILE_NUM=`ls ${UU_ORG} |wc -l`
if [ $UU_FILE_NUM -gt 0 ]
then
...
fi
---
-ne —比較兩個參數是否不相等
-lt —參數1是否小於參數2
-le —參數1是否小於等於參數2
-gt —參數1是否大於參數2
-ge —參數1是否大於等於參數2
-f — 檢查某文件是否存在(例如,if [ -f "filename" ])
-d — 檢查目錄是否存在
判斷目錄是否存在,不存在則創建:
if [ ! -d "glog_log" ]
then
echo "Create glog_log"
mkdir glog_log
fi
10、拷貝文件
本地目錄拷貝:
cp -ri sourcedir deskdir
scp遠程文件拷貝:
scp intersection.exe work@xxxxhost:/home/disk2/cswuyg
將intersection.exe從本機當前目錄拷貝到遠程xxxxhost機器的/home/disk2/cswuyg目錄。
目錄拷貝,加上: -r
把文件從遠程拷貝到本地:
scp root@11.111.1.1:/home/work/cswuyg.test /home/work
注意:scp需要輸入遠端機器密碼
拷貝文件同時也拷貝它的時間:cp -p
11、壓縮/解壓
zip壓縮:
zip -r a.zip /home/disk9/cswuyg
r 表示循環壓縮/home/disk9/cswuyg目錄下的文件。
解壓:unzip a.zip -d dest
tar+gzip壓縮:
tar -zcvf a.tar.gz .
-z 使用gzip來壓縮tar文件
-v 顯示文件的歸檔進度
-c 創建一個新的歸檔
-f 與c選項一起使用時,創建的tar文件使用該選項指定的文件名;與x一起使用時,解除該選項指定的歸檔。
壓縮某類文件:
tar -zcvf a.tar.gz /home/cswuyg/2014-04-08*
解壓到dest目錄:
tar -xzvf a.tar.gz -C dest
-j 使用bzip壓縮:
tar -jcvf a.temp .
bz2格式文件夾解壓
bzip2 -d protobuf-2.5.0.tar.bz2
tar -xf protobuf-2.5.0.tar
把不同目錄下的文件tar到一個包里面:
對打進tar中的文件去除根目錄:tar --transform 's|.*/||g' -zcvvf my.tar.gz a b bb/c
transform跟着換名規則。
資料:
cat filelist | xargs tar -rvf archive.tar --transform='s|.*/||g'
transform可以改變被壓縮文件在tar包中的名字。
12、刪除文件/目錄
rm -r 目錄名
rm -rf 加上-f 不做刪除提示
刪除帶有特殊字符的文件:
先用 ls -i 得到 1 hello world 的inod(就是最前面的數字)假設這個數字是102141122 ,然后
find . -inum 102141122 -exec rm {} \; 就可以刪除了。
結合find刪除有某些特征的文件:
find
. -name
"*.log"
-ctime +7 |
xargs
rm
-f
# 刪除文件變更時間為7天之前且文件名以.log結尾的文件
atime:訪問時間(access time),指的是文件最后被讀取的時間,可以使用touch命令更改為當前時間;
ctime:變更時間(change time),指的是文件本身最后被變更的時間,變更動作可以使chmod、chgrp、mv等等;
mtime:修改時間(modify time),指的是文件內容最后被修改的時間,修改動作可以使echo重定向、vi等等;
13、並發啟動多進程
只需要在shell腳本的每行后面加上 “&” 符號。
譬如:
./uu_all.exe 2014-03-20 1 > uu_old_2014-03-20.txt &
./uu_all.exe 2014-03-21 1 > uu_old_2014-03-21.txt &
14、linux系統定時任務
crontab -l 查詢linux的定時任務,可以使用crontab設置定時啟動某個監控進程
crontab -e 打開該文件進行編輯
譬如:
00 23 * * * /home/disk11/timer_bak.sh > /home/disk11/bak_timer.log
表明在每天23:00 執行timer_bak.sh。
前面的5個*號位分別表示:分鍾(0~59),小時(0~23),天(1~31),月份(1~12),工作日(0~6)。
星號(*)指定該命令在每個時間階段執行,譬如,如果小時位置是*,則表示這個命令每小時執行一次。
如果是要指定第5、第10分鍾執行該命令,那么就在分鍾位置上寫明:5,10,中間用都逗號分隔。
如果要指定每3分鍾執行一次,那么就是在分鍾位置上寫:*/3 這表示遇到能被3整除的分鍾時間時執行該命令。
15、shell下的日期
ye=`date --date='yesterday' +%Y-%m-%d`
echo $ye
這里顯示格式為:2014-04-08
或者:
ye=`date --date='1 days ago' +%Y-%m-%d`
打出更詳細的時間
date "+%G-%m-%d %H:%M:%S"
16、輸出重定向
重定向是 > ,會覆蓋舊數據。
重定向累加是 >> ,不會覆蓋舊數據。
如:python a.py > a.log
17、kill 進程
先 ps -ef | xxx 看xxx進程情況
找到第二列,就是進程號 ,輸入 kill 進程號,如果要強殺,則在kill后面加上-9.
批量殺進程方法1:ps -ef|grep "./xxx.sh" |grep -v grep|cut -c 9-15|xargs kill
批量殺進程方法2:ps + awk
ps -ef|grep "dbpath=/home/cswuyg/shard1" | grep -v grep | awk '{print$2;}' |xargs kill
殺掉所有進程名為uwsgi的進程:killall uwsgi
18、查看linux版本
1)uname -a : 內核版本信息
2)cat /proc/version : 內核版本信息
3)cat /etc/issue : 發行版本信息
4)lsb_release -a : 發行版本信息
19、查看磁盤IO
以MB為單位,每5秒鍾刷新一次輸出:iostat -xtm 5
%util 表明磁盤使用率
rMB/s 表示磁盤讀取
wMB/s 表示磁盤寫入
20、vim下dos格式文件轉為unix格式文件
在windows下編輯的shell腳本,拿到linux下無法運行,或者運行錯誤,很可能是由於編碼問題,需要轉換為unix編碼,vim下的命令:
:set fileformat=unix 或者 :set ff=unix
21、wget拉取數據
wget xxxhost:/home/disk8/cswuyg/uu_2014-04-14.txt
局域網內速度可以達到110MB/s,比scp快很多。
wget最多只能使用后綴通配符,無法使用更高級的通配符。
指定保存文件名:
MAC_REMOTE_MID=遠程ftp路徑
MAC_LOCAL_MID=本地保存路徑
wget ${MAC_D_MID} -O ${MAC_LOCAL_MID}
需要wget版本大於1.10.*版本,需要 ProFTPD 版本大於1.2.6 ,否則不能拉取大於2G的文件。
一個wget去掉層級目錄的例子:
wget -r -nH --cut-dirs=2 ftp://xxxhost:/home/disk1/cswuyg/2014-04-04.tar.gz
下載之后,會在本地創建cswuyg目錄,並把文件下載到該目錄下。
wget拉取文件失敗可能是因為遠程文件權限不足,需要設置被拉取的文件的根目錄:chmod 755 xxx。
22、shell字符串匹配分割
(1) % 從右到左匹配,如${var%.*},從右邊到左邊匹配var變量,發現第一個.,就把.右邊被匹配了的刪除,剩下.左邊的
(2) # 從左到右匹配,如$(var#*\), 發現第一個\,就把左邊的刪除,包括\。
demo:
shell文件,a.sh
a='1234.56&789'
printf ${a%.*}
printf "\n"
printf ${a#*&}
printf "\n"
printf $a
輸出:
%% 表示從右到左貪婪匹配
## 表示從左到右貪婪匹配
demo:
shell文件,a.sh
a='1.2.34&56&789'
printf ${a%%.*}
printf "\n"
printf ${a##*&}
printf "\n"
printf $a
輸出:
23、查看磁盤空間大小
du -c -h --max-depth=1
du -h --max-depth=1 本目錄下,所有文件的size,--max-depth表示遞歸深度為1、
du -c -h *log 查看某類文件大小
24、shell下的通配符
如果在shell下執行命令時,參數里面出現了*、?等通配符,這時候參數會是很多個,會把目錄下的所有符合通配符的文件統統作為參數。
這種對於python的處理非常方便,python收到的就是一個list。
25、查看這個進程當前打開了哪些文件
lsof -p [pid]
or:
ls -l /proc/[pid]/fd/
26、修改文件的群組
work權限的用戶無法操作root權限的文件,所以需要把那些文件的群組從root修改為work。
修改disk0舉例:
先登陸root:su root
然后,遞歸修改:chown -R work disk0
27、讀取文件
#!/bin/bash
while read line
do
echo $line
done < xx.sh
如果不是采用while,而是采用for:
for word in `cat bak_config`
do
echo $word
done
那么,單個單詞也會被當作行輸出。
28、查看命令的可執行程序所在磁盤位置
which ftp
或者使用 type ftp
29、查看進程的啟動位置、可執行文件位置
譬如查找Mongo進程的信息:
ps -ef|grep mongo 得到進程ID,
可執行程序位置: ll /proc/2764/exe
啟動目錄:ll /proc/2764/cwd
打開了哪些文件:
某個進程打開了哪些文件:ls -l /proc/[pid]/fd/
30、find命令查找文件
find / -name inotify.h 表示從根目錄開始查找inotify.h文件。
find . -maxdepth 1 -name "@*" 這個命令意思是,查找當前目錄下以@開頭的文件或者目錄,搜索深度為一級也就是只在當前目錄找,不進入子目錄。
查找當前目錄下的b開頭的文件夾下的以.tgz結尾的文件
find . -name b* -type d -exec ls *.tgz \;
或者:
find . -name b* -type d -exec find *.tgz \;
如果有錯,也許這樣子才可以(多了一個魔術字符串{}):
find . -name 'b*' -type d -exec find {} -name '*.tgz' \;
搜索文本內容:
從根目錄開始查找所有擴展名為.log的文本文件,並找出包含”ERROR”的行:
find / -type f -name "*.log" | xargs grep "ERROR"
打印出包含這特定字符串的文件名:find .|xargs grep -ri "logxxx" -l
批量文件批量替換文本:
查找個數:
find . -type f -name '*.*' | xargs sed -n '/2013-2014/p'
xx換為yy:
find . -type f -name '*.*' | xargs sed -i 's/xx/yy/g'
find . -type f ! -path '*temp_bak*' | xargs sed -n 's/xx/yy/g'
find . -name '*.*' | xargs perl -pi -e 's|old|new|g'
顯示出所有包含xx的內容:find . -name '*.*' -type f | xargs sed -n '/xx/p'
31、查看glibc的版本
方法1:ldd --version; ldd是glibc的一部分,所以它的版本也就是glibc的版本;
方法2:rpm -qa | grep glibc; 在centos下查看安裝了哪些個glibc相關的包;
方法3:ls -l /lib/libc.so.6; 查看libc.so.6指向哪個具體的libc so版本;
方法4:調用C函數獲取:
#include <gnu/libc-version.h>
#include <iostream>
int main(void)
{
std::cout << gnu_get_libc_version() << std::endl;
return 0;
}
注意:網絡上有些人把glibc版本跟gcc版本混在一起了:glibc是Linux版的C語言運行時庫,而GCC是編譯工具。
32、查看Linux Shell操作歷史
vi ~/.bash_history
33、文件鏈接
ln [參數][源文件或目錄][目標文件或目錄]
軟鏈接:
ln -s log2013.log link2013
結果:
link2013 -> log2013.log
硬鏈接:
ln log2013.log link2013
會產生一個一樣大小的文件,它們的鏈接數都會加1
34、crontab下的輸出重定向到/dev/null
crontab里的輸出,會被放到郵件緩存處,如果輸出非常大可能導致tmp磁盤用盡,解決辦法,把輸出放棄掉,也就是重定向到/dev/null:
0 4 * * * xxxcmd >/dev/null 2>&1
2>&1 表示將標准錯誤輸出也輸出到標准輸出中。
標准輸入:0;標准輸出:1;標准錯誤輸出:2。
35、使用bc做計算
echo 10 + 20 |bc
輸出:30
36、查看ELF文件依賴的so庫
ldd XXX.exe
查看所加載的庫:
LD_DEBUG=files ./xxx.exe
LD_DEBUG可以修改為其它:
bindings 顯示動態鏈接符號綁定過程
versions 顯示符號的版本依賴關系
查看so的導出函數:
nm -D 7z.so
objdump -tT 7z.so
37、./mongod啟動出現崩潰解決方法
Floating point exception (core dumped)
解決方法:
LD_DEBUG=libs ./bin/mongod -v 查看所有的加載庫,看在哪里崩潰了。
最后發現是libc版本跟官網上編譯出來的版本不兼容導致的。
38、awk里的if
ps -ef|grep mongo |awk '{if($9=="mongo"){print$9;print$2}}'
含義:把所有mongo進程grep出來,然后以空格、tab鍵分割,第9個字符串如果是mongo,則輸出第9個字符串、第2個字符串。
39、shell取字符串的前12位
a_str=${line:0:12}
或者,玩玩awk:
mac_str=(`echo $line |awk '{$a=substr($0, 0, 12);print($a);}'`)
40、利用iconv實現數據編碼轉換
iconv -c -f unicode -t gb2312 cswuyg*2014-06-17_9.origin > /home/work/a.tmp
-c 表示忽略亂碼
-f 表示源文件編碼
-t 表示目標文件編碼
41、ulimit -a
顯示當前所有資源的限制:
如:
open files (-n) 10240
42、根據IP拿到域名/根據域名拿到IP
host 10.242.92.26 ; 可以得到域名;
host xxxhost ; 可以得到IP;
43、使用rz\sz上傳\下載文件
在secureCRT下,使用rz -bye 上傳文件;
sz 下載文件
rz和sz無法使用時
yum install lrzsz
44、chmod 755是什么意思
你可以在linux終端先輸入ls -al,可以看到如:
-rwx-r--r-- (一共10個參數)
第一個跟參數跟chmod無關,先不管.
2-4參數:屬於user
5-7參數:屬於group
8-10參數:屬於others
接下來就簡單了:r==>可讀 w==>可寫 x==>可執行
r=4 w=2 x=1
所以755代表 rwxr-xr-x
45、使用sendmail發送郵件
[cswuyg@xxxhost ~]$ /usr/sbin/sendmail -t << EOF
> SUBJECT: sendmail test subject
> TO: cswuygxx@xx.com
> mail content
> EOF
46、查看進程因OOM被kill掉的命令
dmesg |grep Kill
***************
Out of memory: Kill process 24145 (python) score 637 or sacrifice child
Killed process 24145, UID 500, (python) total-vm:21423020kB, anon-rss:20930232kB, file-rss:636kB
***************
理解 OOM:
total-vm includes both your physical RAM and swap space.
As I understand, the size of the virtual memory that a process uses is listed as total-vm. Part of it is really mapped into the RAM itself (allocated and used). This is RSS. Part of the RSS is allocated in real memory blocks (other than mapped into a file or device). This is anonymous memory (anon-rss) and there is also RSS memory blocks that are mapped into devices and files (file-rss).
So, if you open a huge file in vim, the file-rss would be high, on the other size, if you malloc() a lot of memory and really use it, your anon-rss would be high also. On the other side, if you allocate a lot of space (with malloc()), but nevers use it, the total-vm would be higher, but no real memory would be used (due to the memory overcommit), so, the rss values would be low.
簡單說:
total-vm表明當前系統可以使用的內存,包括物理內存和交換區空間。
anon-rss表明當前被聲明要使用的內存。
file-rss表明當前映射到磁盤文件的內存。
47、中文顯示亂碼
vim下的亂碼,在vim下執行命令:set encoding=utf-8
SecureCRT的亂碼:在~/.bash_profile添加:export LANG=zh_CN.UTF8 ,然后重新登陸。
48、linux命令行進入vim模式
在命令行中輸入:set -o vi
49、查看資源占用的命令
free -g
top、uptime
sar 1 1
iostat -x 1
50、Linux系統增加用戶 (只允許root執行)
useradd user1 創建一個新用戶
passwd user1 修改一個用戶的口令
51、查看文件系統類型,查看文件系統大小
df -T、
df -h
52、readlink -f 獲取完整路徑
如:readlink -f flume_control
/home/cswuyg/flume/flume_control
53、批量部署時,如何修改crontab
遠程執行修改crontab的shell命令行,譬如:
CMD_BEFORE_COPY = "cd /home/cswuyg/;(crontab -l > crontab_bak.20140522;crontab -l;echo '20 20 * * * find /home/cswuyg/*.pb.log -mtime +3 | xargs rm -f')|crontab"
54、mv 文件后拿着舊文件句柄的程序如何處理
在打日志的時候,可能出現這種情況:a.log重命名為a.log1,后續的日志要求寫入到新的a.log文件。
如果有個進程拿着舊文件的句柄在寫日志,通過mv對文件重命名完之后,雖然文件名改了,但是那個句柄還是有效的,還是在繼續寫舊文件。在日志寫入時,如果要保證寫入到新的a.log文件,代碼中需要檢查a.log文件inode信息是否發生改變,如果改變則重新打開文件。
55、查看Linux進程樹
pstree
56、查看二進制文件內容
od -c a.txt
57、查看網卡流量
(1) watch more /proc/net/dev
(2)watch -n 1 '/sbin/ifconfig eth0|grep bytes'
顯示:
Every 1.0s: /sbin/ifconfig eth0|grep bytes Fri Jun 12 10:41:08 2014
RX bytes:72289863517 (67.3 GiB) TX bytes:161966405143 (150.8 GiB)
RX 為下行流量(接收) TX 為上行流量(發送)
58、統計端口連接數量
netstat -nat | grep 27017 |awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -nr|head -20
統計連接到27017端口的鏈接數
59、一秒鍾的時鍾滴答數,跟CPU主頻無關
這個值在系統編譯時設定的,如:
[work@xxxhost boot]$ cat /boot/config.`uname -r` | grep '^CONFIG_HZ='
CONFIG_HZ=1000
C代碼獲取:
printf ("_SC_CLK_TCK = %ld\n", sysconf (_SC_CLK_TCK));
但是,從配置文件里讀到的跟用C++代碼讀到的不一樣,可能用C++代碼讀到的更准確。
60、單個進程內存使用量的限制
配置文件:/etc/security/limits.conf
61、make並行編譯
編譯C/C++時的shell命令:make -j8 表示8個線程並發編譯,要求makefile要寫好依賴,否則可能會出現錯誤。
62、用shell腳本設置環境變量
shell腳本文件內容:
--------------------------------------------------
export PROTOC=/home/disk1/cswuyg/protobuf/install/bin/protoc
bash
--------------------------------------------------
最后加上bash表明新開一個子shell環境,子shell環境繼承了父shell的環境變量設置,所以PROTOC有效。
如果沒有最后的bash,那么腳本執行完之后,依然是沒有PROTOC變量。
63、查看一個進程的線程信息
pstack [pid] |
egrep
-o
"Thread [0-9]+ [^:]*"
64、top命令
只查看某個process name的多個進程:
top -p $(pgrep -d',' -f "xxx_process_name")
可以使用top輸出到文件:
top -b -n 1 -d 1 –c > top.log
-b batch模式,可以重定向到文件中
-n 一共取2次數據
-d 每次top數據間隔為幾秒
你可以做個crontab任務一分鍾調用一次追加到文件中
-n -d 可以自己設置,單位是s
-c 表示顯示完整命令行
top界面下的顯示操作:
P :根據CPU使用百分比排序
M:根據駐留內存大小排序
1:顯示各個CPU信息
c:顯示完整命令行
65、交換區是否打開
free 命令,看Swap大小。
66、shell腳本的輸入參數
$1是行參變量,也就是腳本執行時的第一個參數。
CHOICE=${1:-NULL}意思是當$1為空時,自動將NULL替換成$1所要帶入的變量值,這里就是$CHOICE為NULL。
67、判斷libstdc++支持哪些glibc庫
strings /usr/lib64/libstdc++.so.6 |grep GLIBC_
后續不定期補充~