跳到主要內容
黯羽輕揚每天積累一點點

文件_bash筆記3

免費2017-03-19#Tool#linux文件权限#diff命令#vps硬盘测速#linux文件名空格

文件相關常識及常用命令

UNIX 系統把一切都看作文件,甚至命令終端也是和一個設備文件關聯在一起的,可以通過向該文件寫入來實現向終端寫入信息,例如:

# 输出到当前终端
echo hoho > /dev/tty

# bash环境,发送到连接在ttys001端口的终端上
echo hoho > /dev/ttys001

dd

用來生成指定大小的文件,常用於硬碟讀寫測速

// 生成测试文件test.data
// 填充\0,大小为10M
dd if=/dev/zero of=test.data bs=1024 count=10k

// 写硬盘测速
// 对磁盘进行连续写入,不使用内存缓冲区,每次写入8k的数据,总共写入4k次,产生32M大小的文件
dd bs=8k count=4k if=/dev/zero of=test.data conv=fdatasync

// 读硬盘测速
dd if=test.data of=/dev/null bs=4k

if 是輸入文件(input file),of 表示輸出文件,bs 寫入塊的大小。/dev/zero 是特殊設備,用來產生無限多的 \0 字元,dev/null 是空設備,輸入的東西都丟掉

P.S. mac 下 conv 參數沒有 fdatasyncfsync 選項

comm

comm 命令用來對比文字檔,實現 diff。但輸入必須是有序的文件,所以一般結合 sort 使用:

# sort命令的-o选项表示输出到文件,这里直接替掉原文件
sort a.txt -o a.txt; sort b.txt -o b.txt
# 做diff
comm a.txt b.txt

P.S. wget-o- 選項長得很有意思,表示 Get as a file and print the result on STDOUT

會得到 3 列結果,分別是:

# a有b没有的 b有a没有的 ab都有的
    a差b       b差a     a交b

有這 3 列就能恢復 a 文件和 b 文件(有序的,排序之前的無法恢復),比如 a=a差b并a交b

-1/-2/-3 選項刪除指定的列,選項必須出現在輸入文件前,例如:

# 去掉第三列,不输出a交b
comm -3 a.txt b.txt

# 把ab的差异合并到1列,结果是ab有差异的行
comm -3 a.txt b.txt | sed $'s/\t//g'

特別注意:正規表示式前面的 $ 取值運算,不加的話比對不到製表符,與 IFS=$'\n' 同理

P.S. Mac 下 sed -i 文件原地替換相當麻煩,必須指定備份檔案名稱(雖然可以空字串)

diff

用來生成差異文件,例如:

# u选项输出更常见的格式,写入diff.txt
diff -u a.txt b.txt > ab.diff

按行比較文件,得出新增了哪些行,刪除了哪些行(修改操作等效於新增新行刪除舊行),結果類似於:

--- a.txt    2017-03-15 10:50:34.000000000 +0800
+++ b.txt   2017-03-19 16:56:14.000000000 +0800
@@ -1,6 +1,11 @@
+
+end yaya
 data
-end
 is
-line
 no
+line
 this
+
+newend
+line

diff 結果給 a 和 b 打補丁就能得到 b 和 a:

# 给a打补丁
patch -p1 a.txt < ab.diff
# ab的内容相同
md5 a.txt; md5 b.txt

要恢復原內容的話再 patch 一次:

# 补丁回来
patch -p1 a.txt < ab.diff

也能對資料夾做 diff

# N不存在的文件视为空文件,a所有文件视为文本文件,r递归比较子目录
diff -Naur data files

mkdir

用來建立資料夾,如果已經存在,就返回錯誤:

mkdir: bak: File exists

一般需要檢查:

# 如果不存在的话,创建
if [ ! -e path ]; then mkdir $path; fi

對於深層路徑,逐級檢查比較費勁,可以簡單丟棄錯誤:

mkdir ./dir1 2>/dev/null
mkdir ./dir1/dir2 2>/dev/null
mkdir ./dir1/dir2/dir3 2>/dev/null

更簡單的做法是:

mkdir -p ./dir1/dir2/dir3

忽略已經存在的,建立需要建立的

文件權限

常見的 3 類權限:

  • user:文件的 owner

  • group:用戶組

  • others:除 user 和 group 用戶外的用戶

ls -l 列出的文件權限格式為:文件類型(1 位)user 權限(3 位)group 權限(3 位)others 權限(3 位)

文件類型如下:

- 普通文件
d 目录
c 字符设备
b 块设备
l 符号链接
s 套接字
p 管道

後面的 3 位權限每位取值有 4 種:-rwx,分別表示 無/讀/寫/執行

P.S. 如果文件權限是 ---------- 的話,表示除 root 外的所有用戶都沒有權限處理該文件,無法讀寫執行

另外有 3 種特殊權限,會出現在 x 的位置:

  • setuid:允許用戶以 owner 權限來執行文件,比如 -rws------

  • setgid:允許用戶以 owner 所在組權限來執行文件,比如 ----rws---

  • sticky bit:粘滯位,只有建立該目錄的用戶才有權限刪除下面的文件,其他用戶即便有寫權限也刪不了,比如 -------rwt

注意:st 都有大小寫兩種,區別是 s 表示有 x 權限,S 表示沒有 x 權限

修改權限

chmod 命令,例如:

# 设置权限
chmod u=rwx g=rwx o=rwx test.sh
# 添加user执行权限
chmod u+x test.sh
# 添加所有执行权限
chmod a+x test.sh
# 删除user权限
chmod u-x test.sh

也可以用數值來設置權限:

# 等价于u=rwx g=rwx o=rwx
chmod 777 test.sh

777 是 3 組 rwx 二進位表示對應的十進位數,比如 r-- 為 4(100

P.S. 一般把這個叫八進位值(值為 0 到 7 都不超過 8?),實際上二進位解釋更合理

設置 3 個特殊權限也用 chmod

# setuid, setgid, sticky bit
chmod u+s
chmod g+s
chmod o+t

用數值設置的話,在 3 種權限前添一組 sst,例如 chmod 2777 test.sh 中的特殊權限是 2(010),也就是 -s- 表示 setgid 權限

修改所屬權的命令是 chown

# 设置属于user1用户,属于staff组
chown user1.staff test.sh

一般配合 setuid 權限使用:

# root组root用户
chown root.root bomb.sh
# 如朕亲临
chown u+s bomb.sh

touch

touch 摸一摸,存在的話更新時間戳記,不存在的話建立一個空文件:

# 存在的话,更新所有时间戳为当前时间
touch test.sh
# 存在的话,只更新访问时间
touch -a test.sh
# 存在的话,只更新修改时间
touch -m test.sh

head/tail

只查看文件內容的某一部分,例如:

# 看前10行
head test.sh
# 看前3行
head -n 3 test.sh
# 不看后10行
head -n -10 test.sh

# 看后10行
tail test.sh
# 看后3行
tail -n 3 test.sh
# 不看前90行(输出第91行到结束)
seq 100 | tail -n +91

P.S. mac 下 -n 參數不能是負數,會報錯 head: illegal line count -- -10

ls 只列出目錄

有 3 種方法:

# d选项最简洁
ls -d */
# F添上类型标识,筛选/结尾的
ls -F | grep "/$"
# l选项结果以权限开头,权限以类型开头,筛选d开头的
ls -l | grep "^d" | awk '{print $9"/"}'

也可以用 find

# 按文件类型查找
find . -type d -maxdepth 1 -mindepth 1 -print

注意 depth 範圍,只找下一級

路徑切換

經常用 cd -cd $OLDPWD)返回上次工作路徑,實際上還有更強大的:

# 与cd作用看似相同
pushd /tmp
# 查看历史路径栈(-v编号)
dirs -v
# 返回上一次工作路径
pushd
# 返回上上一次...
pushd +1
# 返回上上上一次...
pushd +2

pushd 用來切換工作路徑,交換棧頂記錄與指定記錄,但歷史棧長度不變,需要刪除記錄的話,用 popd

# 返回上一次工作路径,并删除当前路径
popd
# 删除上上一次工作路径
popd +1
# 清空历史栈(只保留当前记录)
dirs -c

+N-N 表示方向,+N 從棧頂開始數 0123...-N 從棧底開始數

P.S. 注意 og my zsh 某個版本 +- 方向是反的,bash 正常

wc

統計行數、單字數、字元數,常用於簡單的程式碼統計:

# 输出行数、单词数、字符数
wc test.sh
# 取行数
wc -l test.sh | awk '{print $1}'
# 取单词数
wc -w test.sh | awk '{print $1}'
# 取字符数
wc -c test.sh | awk '{print $1}'

P.S. 數單字的功能很弱,空格隔開的字串就算一個單字,也不區分標點符號

評論

暫無評論,快來發表你的看法吧

提交評論