Skip to content

antony@notes:~/data-platform$ cat "Linux-Data-Process.md"

Linux Data Process

2022-09-08· data-platform ·資料科技平台

Linux Data Process

:::warning

:::spoiler 目錄 ( :mag_right: 點我,可展開 )

[TOC]

:::

上課補充

RAID 5

ExFAT 檔案系統

formathdfs 程式解析

$ cat /opt/bin/formathdfs
#!/bin/bash  

m="dtm1"
w=$(cat /etc/hosts | grep -e ' dtw[0-9]' | cut -d' ' -f3)

read -p "Are you sure ? (YES/NO) " ans
[ $ans != "YES" ] && echo "abort format HDFS" && exit 1

ssh "$m" rm -r nn/* sn/* &>/dev/null
[ "$?" == "0" ] && echo "$m rm ok"

for n in $w
do
   nc -w 1 -z $n 22 &>/dev/null
   [ "$?" == "0" ] && ssh $n rm -r dn/* &>/dev/null && echo "$n rm ok"
done

ssh $m 'hdfs namenode -format -clusterID cute' &>/dev/null
[ "$?" != "0" ] && echo "formathdfs failure" && exit 1
echo "formathdfs ok"
  • 第一行 | 宣告下面的程式用 /bin/bash 貝殼程式執行,這行如果是 #!/bin/pyton3 ,那麼下面的程式就會用 python3 執行
  • /etc/hosts 5 顆星重點,hacker 可能會偷改一個名稱對應的 ip ,所以要注意。
  • nn/ namenode 的 metadata
  • nc | netcat -w 1 | 等待一秒 22 | port 號 -z | 不要回應資訊
  • &>/dev/null 標準輸出和錯誤輸出都丟到黑洞
  • nc -w $ip 445 ,如果有通代表對方 windows 電腦沒開防火牆
  • -format 將 hdfs 檔案系統初始化
  • -clusterID ,聯邦制,一座 Hadoop 的名稱,在哪一間公司架 Hadoop ,就可以設該間公司的代號

hls hadoop list

$ hls
[dtm1]
8208 SecondaryNameNode  ----> pid javaprogram_name
8092 NameNode

[dtm2]
8002 ResourceManager
8083 JobHistoryServer ---> 秘書,yarn 運作完之後,會跟它報告自己的運作資訊,用了多少資源

[dtw1]
8584 DataNode  ---- > 存取資料
8729 NodeManager ----> 負責跑 spark 和 mapreduce 的程式

[dtw2]
8553 DataNode
8698 NodeManager

[dtw3]
8535 DataNode
8681 NodeManager
  • mapreduce 一定是 Java 語言才能跑, hive 可以讓你打 SQL 命令,將這些命令翻譯成 Mapreduce 的 Java 程式,pig 豬小弟也是
$ stopyarn; stophdfs
";" 代表不管前面的命令是成功還是失敗,做完緊接著做後面的命令
"&&" 前面的命令執行成功,後面的命令才會執行
  • 關機如果很久一定要等他做完,才能將電腦關機
  • 重要的系統資訊一定要備份

echo 命令解析

$ echo -n No new line
No new linebigred@dta1:~$
  • -n ,字串顯示不會換行
$ echo -e "A line with an escaped\nreturn"
  • -e ,可以轉義,使 “\n” 生效,變成換行符號

字串變大小寫

$ a="aBc"

$ echo ${a^^}
ABC

$ echo ${a,,}
abc

$ echo $a
aBc

補充連結

$ echo '#!/bin/sh
echo "let me go" ' > myecho.sh

">" | 重導 ( redirection ),將原本輸出在螢幕上的字串,重導到 myecho.sh 這個檔案

練習

請撰寫程式 myart.sh 將以下文字圖列印出來 :

:::spoiler 解答

$ nano art.txt
(\(\
( -.-)
o_('')('')

$ nano myart.sh
#!/bin/bash

cat ~/art.txt

$ ./myart.sh
(\(
( -.-)
o_('')('')

注意,盡量不要把變數寫死! 優點 : 方便交接,且阿罵來也會寫 如果用以下方法寫,難交接。

$ cat myart.sh
#!/bin/bash

echo -e "(\(\\\\\n( -.-)\no_('')('')"

:::


操作範例 - 顯示記憶體大小

$ free -mh | grep "Mem"
Mem:           2.9Gi        98Mi       2.7Gi       0.0Ki       122Mi       2.8Gi

$ free -mh | grep "Mem" | tr -s " "
Mem: 2.9Gi 98Mi 2.7Gi 0.0Ki 122Mi 2.8Gi

$ free -mh | grep "Mem" | tr -s ' ' | cut -d " " -f 2
2.9Gi

# 利用 $() 把命令寫到一個變數裡面
$ m=$(free -mh | grep "Mem" | tr -s " " | cut -d " " -f 2)

$ echo "Memory : ${m}"
Memory : 2.9Gi

# 將我們寫的 program 加到 PATH 環境變數裡面的目錄
$ sudo cp sysinfo /usr/bin/

操作範例 - 取出 CPU 型號

此命令可以得知 cpu 型號,幾行代表幾核

$ cat /proc/cpuinfo | grep 'model name'

output :

model name      : Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz
model name      : Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz

做一些處理

$ cat /proc/cpuinfo | grep 'model name' | head -n 1 | cut -d ":" -f 2
 Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz

丟到變數 c 裡面

$ c=$(cat /proc/cpuinfo | grep 'model name' | head -n 1 | cut -d ":" -f 2)

排版後,透過 echo 命令印出

$ echo "CPU:${c}"
CPU: Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz

練習 得出 cpu 幾核心

$ n=$(cat /proc/cpuinfo | grep 'model name' | wc -l)

$ echo "CPU:${c} ($n)" 

丟到 /user/bin/ 目錄裡面

$ nano sysinfo
#!/bin/bash

m=$(free -mh | grep "Mem" | tr -s " " | cut -d " " -f 2)
echo "Memory : ${m}"

c=$(cat /proc/cpuinfo | grep 'model name' | head -n 1 | cut -d ":" -f 2)
n=$(cat /proc/cpuinfo | grep 'model name' | wc -l)
echo "CPU :${c} (${n})"

$ sudo cp ./sysinfo /usr/bin/sysinfo

$ sysinfo
Memory : 2.9Gi
CPU : Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz (2)

操作範例 - 取出硬碟大小

$ df  -h | grep /dev/sda
/dev/sda2       1.9T   78G  1.7T   5% /opt

:::spoiler 問題 : 如何只取出上面結果的 “1.9T” 這幾個字

答 :

$ df  -h | grep /dev/sda | tr -s " " | cut -d " " -f 2

:::

$ wget -qO - https://www.oc99.org/sys/sysinfo | bash
  • -q 代表靜音模式(不顯示指令輸出)
  • -O 將檔案輸出(大寫的 O)
  • - 標準輸出裝置(利用螢幕作為輸出目標),Linux 的 1 號裝置
  • | bash 把左邊命令輸出的內容丟給 bash 執行
  • 結果:在螢幕裝置輸出,丟給 bash 執行,不會把程式下載下來,與顯示指令輸出

output :

Host : dta1
Memory : 2.9Gi
CPU :  Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz (core: 2)

:::spoiler 老師的程式碼

#!/bin/bash
echo "Host : `hostname`"

m=$(free -mh | grep Mem:)
echo -n "Memory : "
echo $m | cut -d' ' -f2

cn=$(cat /proc/cpuinfo | grep 'model name' | head -n 1 | cut -d ':' -f2)
echo -n "CPU : $cn (core: "
cn=$(cat /proc/cpuinfo | grep 'model name' | wc -l)
echo "$cn)"

:::


DT-ELT-HDFS

dataset ( 資料集 )

hadoop -> Schema on read 傳統 IT -> Schema on write

取得藥局基本資料集

# 下載資料
$ wget 'https://quality.data.gov.tw/dq_download_csv.php?nid=6134&md5_url=03c3b7e3b7f5433d15b92b8f7af15b49' -O drugstore.csv
# 認識資料
$ head -n 3 drugstore.csv
機構狀態,機構名稱,地址縣市別,地址鄉鎮市區,地址街道巷弄號,負責人姓名,負責人性別,電話,是否為健保特約藥局
開業,活力健康藥妝藥局,臺北市,中正區,中華路二段315巷1號,蕭聖鈞,男,23392625,Y
開業,建祥武昌藥局,臺北市,中正區,武昌街1段29號1樓,黃盟婷,女,2381-5229,Y

要對資料的每一個欄位有些想法

$ cat drugstore.csv | grep '臺北市'
.......
"開業","忠孝藥局","臺北市","南港區","成福路16號","黃雅惠","女","(02)2786-2829","Y"
"開業","躍獅京華藥局","臺北市","松山區","南京東路五段71號","賴煌濱","男","(02)2766-6508","Y"
"開業","農安盛康藥局","臺北市","中山區","農安街267號","葉惠茹","女","(02)25038205","Y"
.......

台北市有多少家藥局 ?

$  cat drugstore.csv | grep '臺北市' | wc -l
754

多少縣市有藥局 ?

$ cat drugstore.csv | cut -d',' -f3 > drugstore.tmp
......
澎湖縣
澎湖縣

# tail -n +2 ,從第二行開始顯示到最後一行 --> 移除第一行
# tr -d \" | delete ""
$ tail -n +2 drugstore.csv > drugstore.tmp

# sort | 將資料重新排序
# uniq | 命令是把連續相同資料, 變為一筆資料, 不連續的相同資料則各別處理
$ cat drugstore.tmp | cut -d',' -f3 | sort | uniq > drugcity.tmp

$ head -n 2 drugcity.tmp
南投縣
嘉義市

sort 命令解析

描述 :

  • 對文本文件進行排序。
  • 對給定文件(或標準輸入)中的所有行進行排序、合併或比較。
$ sort [ options ] [ file ...] 

sort 指令

  • 預設 ( no options )
    • 目前找到的規律有以下,並不完整 :
    • 英文字母 a ~ z 排序 每一行資料 ( 不分大小寫 )
    • 數字 由小到大 排序每一行
    • 如果數字和英文在同一行比,數字優先
  • -n 按數值大小排序
  • -r 倒轉排序, 即從大至小排序
  • -R 隨機的方式重新排序,但相同值的排序還是會排在一起
  • -t 指定欄位分隔的字符, 預設是 空白 或 tab
  • -k 要排序的欄位,指定欄位時輸入的兩個數字代表「起始位置」與「結束位置」,而如果將結束位置省略的話,預設的結束位置就是整行的結尾。
  • what is difference between “sort -u” and “sort | uniq” ( 連結 )

下載老師的資料

$ wget http://www.oc99.org/dt/dataset/mycsv.zip

$ unzip mycsv.zip (A 覆蓋)

取得完整縣市名冊

$ cat tw.103.zipcode.csv | cut -d ',' -f 1 | sort | uniq > zipcode

顯示沒有藥局的縣市

$  join -v 2 drugcity.tmp  zipcode

-v 2 用 zipcode 去比對 drugcity.tmp,顯示沒有對到的資訊

output :

南海諸島
連江縣
釣魚臺

旅行社會需要這種資訊


全臺灣大專校院科系別概況(含學生數,畢業生數,教師數)

透過 wget 抓取 103 年全臺灣大專校院科系別資料集

wget 'http://stats.moe.gov.tw/files/detail/103/103_sdata.csv' -O 103_sdata.csv

檢視資料

$ head -n 3 103_sdata.csv
學校代碼,學校名稱,科系代碼,科系名稱,日間∕進修別,等級別,學生數,教師數,上學年度畢業生數,縣市名稱,體系別
0001,國立政治大學,140101,教育學系,D 日,D 博士,93,0,16,30 臺北市,1 一般
0001,國立政治大學,140101,教育學系,D 日,M 碩士,34,0,10,30 臺北市,1 一般

得知政大為台灣第一所大學

查詢有數學系的大學

$ cat 103_sdata.csv | grep "數學系"

查詢全台灣的大學有數學系的有幾間

$ cat 103_sdata.csv | grep '數學系' | cut -d ',' -f 2 |  sort | uniq | wc -l
31

wc | word count

:::spoiler 問 : 查詢 104 105 的資料

答 :

$ wget 'http://stats.moe.gov.tw/files/detail/104/104_sdata.csv' -O 104_sdata.csv

$ wget 'http://stats.moe.gov.tw/files/detail/105/105_sdata.csv' -O 105_sdata.csv

$ cat 104_sdata.csv | grep '數學系' | cut -d ',' -f 2 |  sort | uniq | wc -l
31

$ cat 105_sdata.csv | grep '數學系' | cut -d ',' -f 2 |  sort | uniq | wc -l
30

:::

$ cat getsdata.sh
#!/bin/bash

declare -i y

for ((y=103;y<=110;y=y+1))
do
  [ -f s${y}.csv ] && rm s${y}.csv
  wget "http://stats.moe.gov.tw/files/detail/${y}/${y}_sdata.csv" -O s${y}.csv &>/dev/null
  [ "$?" != "0" ] && echo "download s${y}.csv failure" && continue
  echo "s${y} ok"
done

[ ! -d  opendata/s ] && mkdir -p opendata/s
mv s*.csv opendata/s

HDFS 基本操作命令

操作命令 (一)

$ wget -qO - http://www.oc99.org/dt/getcsv.sh | bash

下載好的資料會放在

$ ls -l | grep mycsv
drwxr-sr-x 2 bigred bigred      4096 Jul 13 10:15 mycsv
-rw-r--r-- 1 bigred bigred    348134 Jul 11  2021 mycsv.zip

老師的程式

#!/bin/bash

wget http://www.oc99.org/dt/dataset/mycsv.zip -O /tmp/mycsv.zip &>/dev/null
[ "$?" != "0" ] && echo "get mycsv.zip failure" && exit 1

[ ! -d ~/mycsv ] && mkdir ~/mycsv/
cd ~/mycsv; unzip -o /tmp/mycsv.zip &>/dev/null

tree -L 1 ~/mycsv

從這個階段開始 bigred 使用者會有兩個家

/home/bigred – > linux ext4 檔案系統的家 /user/bigred – > 別墅區,放大數據的家 ( hdfs 分散式檔案系統的家 )

顯示使用者 HDFS 家目錄

$ pig -e "pwd" 2>/dev/null
hdfs://dtm1:8020/user/bigred
  • -e, -execute - Commands to execute ( within quotes 在引號內 )
  • 2 ,錯誤訊息裝置
  • dtm1 的 namenode 程式,打開 TCP/IP 的一個 8020 port
  • neamenode 紀錄 hdfs 的 metadata

在 HDFS 上面建立目錄

$ hdfs dfs -mkdir mydataset
  • hdfsUsage: hdfs [OPTIONS] SUBCOMMAND [SUBCOMMAND OPTIONS]
  • dfs ,hdfs 的子命令, run a filesystem command on the file system.

檢查是否符合預期

$ hdfs dfs -ls
Found 2 items
drwxr-xr-x   - bigred bigboss          0 2022-07-12 10:41 .sparkStaging
drwxr-xr-x   - bigred bigboss          0 2022-07-13 10:32 mydataset

檢視 客戶資訊 的前兩行 ( 注意,此時在 linux 的 ext4 檔案系統 )

$ head -n 2 ~/mycsv/customer.csv
4000001,Kristina,Chung,55,Pilot
4000002,Paige,Chen,74,Teacher

將 客戶資訊 搬到 hdfs 分散式檔案系統中的 mydataset 目錄

$ hdfs dfs -put ~/mycsv/customer.csv mydataset/

[重要] 管理目錄, 記得目錄名稱最後要加上 “/”

hdfs 的語法與 linux 的命令結合 看

$ hdfs dfs -cat mydataset/customer.csv | head -n 3
4000001,Kristina,Chung,55,Pilot
4000002,Paige,Chen,74,Teacher
4000003,Sherri,Melton,34,Firefighter

練習 :

  1. 請在 HDFS 建立以下目錄架構 ? mydataset |–US |–TW
$ hdfs dfs -mkdir -p mydataset/{US,TW}
bigred@dta1:~$ hdfs dfs -ls mydataset
Found 3 items
drwxr-xr-x   - bigred bigboss          0 2022-07-13 10:47 mydataset/TW
drwxr-xr-x   - bigred bigboss          0 2022-07-13 10:47 mydataset/US
-rw-r--r--   2 bigred bigboss        695 2022-07-13 10:36 mydataset/customer.csv
  1. 請將 Linux 的 /etc/hosts 檔案上傳至 HDFS 檔案系統的 mydataset/TW 目錄中
$ hdfs dfs -put /etc/hosts mydataset/TW/

$ hdfs dfs -ls mydataset/TW/
Found 1 items
-rw-r--r--   2 bigred bigboss        216 2022-07-13 10:49 mydataset/TW/hosts

$ hdfs dfs -cat mydataset/TW/hosts
127.0.0.1 localhost alp
192.168.61.0 x1
192.168.61.1 x2 www.microsoft.com
192.168.61.2 x3
192.168.61.3 dta1
192.168.61.4 dtm1
192.168.61.5 dtm2
192.168.61.6 dtw1
192.168.61.7 dtw2
192.168.61.8 dtw3
192.168.61.9 dtw4

為何不能用 hdfs dfs -cp /etc/hosts mydataset/TW/ ? 因為 hdfs dfs -cp 不能跨檔案系統複製,只能在 hdfs 內自己拷貝


103 年大專校院名錄檔

++下載資料++

$ wget --no-check-certificate https://stats.moe.gov.tw/files/school/103/u1_new.txt
  • --no-check-certificate don’t validate the server’s certificate

++看 u1_new.txt 的內容++

$ head -n 3 u1_new.txt
T 3x[t^^'\!hb

T1z     0W@W    q       }@W     Ԛ|%R

跨簍謀 ? ? ?

++看檔案編碼++

$ file -bi u1_new.txt
text/plain; charset=utf-16le
  • $ file -bi [filename]
    • 描述 : 檢查文件中使用的編碼
    • -b, --brief | 不打印文件名(簡要模式)
    • -i, --mime | 打印文件類型和編碼
  • 參考連結

linux 系統大部分設定的編碼為 utf-8

  • utf-16
    • 16 單位是 bit
    • 16 bit = 2 bytes
    • 文字的語言都用 2 個 byte 在描述,因 1 個 byte 只有 256 個不夠,兩個才有 6 萬多個
    • 如果用 2 個 byte 去描述英文,會浪費太多
    • 適合儲存東方語系的中文
  • utf-8
    • 存中文為 3 個 byte
    • 不適合存中文的文字
    • 適合英文語系的系統

++轉換資料格式 ( 在做資料處理時,不要動到原始檔 )++

$ iconv -f utf-16le -t utf8 u1_new.txt >103u.txt
  • iconv 命令解析
    • 功能描述 : 將文本從一種字符編碼轉換為另一種
    • -f from-encoding | 檔案原本的編碼
    • -t to-encoding | 要轉換的編碼
    • -c | 從輸出中省略無效字符
    • 範例 : iconv -f utf-16le -t utf8 u1_new.txt
      • 描述 : 將 u1_new.txt 這個檔案從 utf-16le 編碼 轉換為 utf8 編碼
    • 參考文件連結

++看轉碼後的檔案前四列++

$ head -n 4 103u.txt
 103學年度大專校院名錄

代碼    學校名稱        縣市名稱        地址    電話    網址    體系別
0001    國立政治大學    [38]臺北市      [116]臺北市文山區指南路二段64號 (02)29393091    http://www.nccu.edu.tw                                   [1]一般

++將資料丟到 hdfs 分散式檔案系統中++

$ hdfs dfs -put 103u.txt mydataset/

# 檢查是否符合預期
$ hdfs dfs -ls  mydataset
Found 4 items
-rw-r--r--   2 bigred bigboss      20807 2022-07-13 11:31 mydataset/103u.txt
drwxr-xr-x   - bigred bigboss          0 2022-07-13 10:49 mydataset/TW
drwxr-xr-x   - bigred bigboss          0 2022-07-13 10:47 mydataset/US
-rw-r--r--   2 bigred bigboss        695 2022-07-13 10:36 mydataset/customer.csv

++下載 108 年的資料++

$ wget --no-check-certificate https://stats.moe.gov.tw/files/school/108/u1_new.csv

++查看資料++

$ file -bi u1_new.csv
text/csv; charset=utf-8

$ head -n 3 u1_new.csv
代碼,學校名稱,公/私立,縣市名稱,地址,電話,網址,體系別
0001,國立政治大學,公立,[38]臺北市,[116]臺北市文山區指南路二段64號,(02)29393091,http://www.nccu.edu.tw,[1]一般
0002,國立清華大學,公立,[18]新竹市,[300]新竹市東區光復路二段101號,(03)5715131,http://www.nthu.edu.tw,[1]一般

++題目 :++

1.先建立以下文字檔並上載至 HDFS 檔案系統

$ echo "224.2.2.2 ICRT" > radio.txt
$ hdfs dfs -put radio.txt mydataset/TW/

請將 “224.1.1.1 FM989” 這行字串增加到 mydataset/TW/radio.txt 檔案的開頭

++答 :++

一定要先在外面修改完,才能丟到 hdfs 分散式檔案系統中,因為 hadoop 被設計出來就是要處理 raw data ,即不能更改資料內容,只能從後面新增資料

# 編輯檔案
$ nano radio.txt
224.2.2.2 ICRT
224.1.1.1 FM989

# -f 強制覆蓋 radio.txt 到原本的檔案
$ hdfs dfs -put -f radio.txt mydataset/TW/

# 檢查是否符合預期
$ hdfs dfs -cat mydataset/TW/radio.txt
224.2.2.2 ICRT
224.1.1.1 FM989

注意 ! hive 的命令一樣不支援 SQL 語法的 update 和 delete 的命令 ! 如果硬要處理,底層要有一個專門處理資料的 system 來支援。

hdfs dfs -appendToFile 只支援從本地端的檔案系統中的資料 append 到 hdfs 檔案系統中的資料

  • 網路硬碟
  • Network ? Server
  • 大家可以透過網路一起存取硬碟

HDFS 協同作業系統

建立 Linux 帳號

# 在 dta1 終端機, 執行以下命令
$ echo -e "rbean\nrbean" | sudo adduser -h /home/rbean -s /bin/bash rbean
Changing password for rbean
New password:
Bad password: similar to username
Retype password:
passwd: password for rbean is unchanged

$ echo -e "gbean\ngbean" | sudo adduser -h /home/gbean -s /bin/bash gbean
Changing password for gbean
New password:
Bad password: similar to username
Retype password:
passwd: password for gbean is unchanged
  • 六個空白,hacker 也很難破解,越多空白越難破解
  • 參數前面如果只有一個 “-",後面的英文大多都是簡寫
  • 參數前面如果只有一個 “--",後面的英文大多都是完整的英文單字
  • 刪除使用者須借用最高的管理員權限 –> sudo | super user do

++刪除 rbean 和 gbean 使用者++

$ sudo deluser --remove-home rbean
deluser: can't find rbean in /etc/group

$ sudo deluser --remove-home gbean
deluser: can't find gbean in /etc/group

建立資料分析師家目錄

建立 rbean、gbean 和 bigred 在 hdfs 檔案系統中的家目錄

$ hdfs dfs -mkdir -p /user/{rbean,gbean,bigred}

# 檢查是否符合預期
$ hdfs dfs -ls /user
Found 3 items
drwxr-xr-x   - bigred bigboss          0 2022-07-13 10:32 /user/bigred
drwxr-xr-x   - bigred bigboss          0 2022-07-13 14:01 /user/gbean
drwxr-xr-x   - bigred bigboss          0 2022-07-13 14:01 /user/rbean

更改 rbean 和 gbean 使用者在 hdfs 家目錄的權限

$ hdfs dfs -chown rbean:rbean /user/rbean
$ hdfs dfs -chown gbean:gbean /user/gbean

# 檢查是否符合預期
$ hdfs dfs -ls /user
Found 3 items
drwxr-xr-x   - bigred bigboss          0 2022-07-13 10:32 /user/bigred
drwxr-xr-x   - gbean  gbean            0 2022-07-13 14:01 /user/gbean
drwxr-xr-x   - rbean  rbean            0 2022-07-13 14:01 /user/rbean

刪除 rbean 和 gbean 使用者在 hdfs 家目錄

$ hdfs dfs -rm -r /user/rbean
Deleted /user/rbean

寫一隻 mkuser 和 rmuser

$ cat mkuser
#!/bin/bash

clear
u=(rbean gbean ybean)

for n in ${u[@]}
do
  cat /etc/passwd | grep "^$n" &>/dev/null
  if [ "$?" == "0" ]; then
    echo "linux ${n} user 已存在"
  else
    echo -e "${n}\n${n}" | sudo adduser -h /home/${n} -s /bin/bash $n &>/dev/null
    [ "$?" == "0" ] && echo "linux ${n} user ok"
  fi
  hdfs dfs -ls /user | grep "$n" &>/dev/null
  if [ "$?" == "0" ]; then
    echo "hdfs ${n} user 已存在"
  else
    hdfs dfs -mkdir /user/${n} &>/dev/null && hdfs dfs -chown ${n}:${n} /user/${n}
    [ "$?" == "0" ] && echo "hdfs ${n} user ok"
  fi
done
$ cat rmuser
#!/bin/bash

u=(rbean gbean ybean)

for n in ${u[@]}
do
  hdfs dfs -ls /user | grep "$n" &>/dev/null
  if [ "$?" == "0" ]; then
    hdfs dfs -rm -r /user/${n} &>/dev/null && echo "hdfs ${n} user 刪除成功 !"
  else
    echo "hdfs ${n} user 不存在"
  fi
  cat /etc/passwd | grep "^$n" &>/dev/null
  if [ "$?" == "0" ]; then
    sudo deluser --remove-home ${n} &>/dev/null && "linux ${n} user 刪除成功 !"
  else
    echo "linux ${n} user 不存在"
  fi
done

:::spoiler 老師的解答 :

:::

第二題 批次建 linux user 帳號,帳號名稱要拉出程式

#!/bin/bash

clear

[ "$1" = "" ] && echo "please give me a file, thx !" && exit 1

[ ! -f "$1" ] && echo "No such file, if file name is correct, pls check path, thx !"

while read line
do
  a=$(echo $line | cut -d "," -f 1)
  cat /etc/passwd | grep -w "^${a}" &>/dev/null
  [ "$?" == "0" ] && echo "${a} user exist" && continue
  p=$(echo $line | cut -d "," -f 2)
  echo -e "${p}\n${p}" | sudo adduser -s /bin/bash $a &>/dev/null
  [ "$?" == "0" ] && echo "${a} user created" || (echo "create ${a} user error!" && continue)
done < $1

sleep 2 && echo ""
echo "執行結束"
exit 0

$ hdfs dfs -mkdir /app

$ hdfs dfs -ls /
Found 3 items
drwxr-xr-x   - bigred bigboss          0 2022-07-13 15:01 /app
drwxrwxrwx   - bigred bigboss          0 2022-07-12 10:40 /tmp
drwxr-xr-x   - bigred bigboss          0 2022-07-13 14:54 /user

為何 bigred 使用者 可以在 hdfs 檔案系統的根目錄上建立目錄 ? 因為當初是 bigred 使用者 formathdfs 檔案系統,所以 bigred 使用者為 hdfs 的管理者 結論 : 哪個使用者 formathdfs ,誰就是 hdfs 檔案系統的管理員

將 mkuser 和 rmuser 丟到 hdfs 的 /app 目錄中

$ hdfs dfs -put mkuser /app/
$ hdfs dfs -put rmuser /app/

# 檢查是否符合預期
$  hdfs dfs -ls /app/
Found 2 items
-rw-r--r--   2 bigred bigboss        568 2022-07-13 15:07 /app/mkuser
-rw-r--r--   2 bigred bigboss        471 2022-07-13 15:07 /app/rmuser
# 透過 ssh 命令,連線到 dtm1 機器
$ ssh dtm1

# 看 hdfs 的 /app 目錄 
$ hdfs dfs -ls /app
Found 2 items
-rw-r--r--   2 bigred bigboss        568 2022-07-13 15:07 /app/mkuser
-rw-r--r--   2 bigred bigboss        471 2022-07-13 15:07 /app/rmuser

使用者如何執行剛剛丟到 hdfs 的 /app 目錄中的程式

# 執行
$ hdfs dfs -cat /app/mkuser | bash

# 檢查是否符合預期
$ tail -n 3 /etc/passwd
rbean:x:1002:1002:Linux User,,,:/home/rbean:/bin/bash
gbean:x:1003:1003:Linux User,,,:/home/gbean:/bin/bash
ybean:x:1004:1004:Linux User,,,:/home/ybean:/bin/bash
$ hdfs dfs -mkdir /dataset

$ hdfs dfs -rm -r /dataset
Deleted /dataset

$ hdfs dfs -put mycsv/customer.csv /dataset

$ hdfs dfs -ls /
Found 4 items
drwxr-xr-x   - bigred bigboss          0 2022-07-13 15:07 /app
-rw-r--r--   2 bigred bigboss        695 2022-07-13 15:42 /dataset
drwxrwxrwx   - bigred bigboss          0 2022-07-12 10:40 /tmp
drwxr-xr-x   - bigred bigboss          0 2022-07-13 14:54 /user

$ hdfs dfs -rm /dataset
Deleted /dataset

$ hdfs dfs -put mycsv/customer.csv /dataset/
put: `/dataset/': No such file or directory: `hdfs://dtm1:8020/dataset'

連線到 dta1 的 rbean 使用者

$ hdfs dfs -mkdir mydata/

$ hdfs dfs -cp /dataset/customer.csv  mydata/

$ hdfs dfs -rm mydata/customer.csv
Deleted mydata/customer.csv

$ exit

lake.sehema 設計協同作業目錄架構

描述 : 這支程式在建立 協同作業的環境

以下命令回到 bigred

$ lake.schema
/raw/ (bigred:bigboss,755) 
/elt/ (bigred:bigboss,755)  
/dataset/ existed 
/apps/ (bigred:bigboss,755) 
/metadata/ (bigred:bigboss,755) 
/tmp/hive created (Jupyter)
/tmp (777)

執行完成
  • /raw/ | 放 raw data
  • /elt/ | 放一堆處理資料的程式,不論是 python 或是 bash script 都可以
  • /dataset/ | 放 elt 目錄下程式執行完,處理後的資料
  • /apps/ | 放 system 維運的程式, 像是 mkuser ,rmuser
  • /metadata/ | 放 hive 工具要用的 schema ,因為 SQL 命令要跑會需要資料的 schema
    • schema | 資料的欄位 and 欄位屬性

設定 HDFS Access Control List ( 簡稱 : ACL )

linux 檔案系統也有這種機制

$ hdfs getconf -confKey dfs.namenode.acls.enabled
true

$ hdfs dfs -setfacl -m user:rbean:rwx  /apps/

$ hdfs dfs -getfacl /apps
# file: /apps
# owner: bigred
# group: bigboss
user::rwx
user:rbean:rwx
group::r-x
mask::rwx
other::r-x

自製 sysinfo 系統命令, 上載至 /apps

# 在 rbean  終端機執行以下命令
$ echo $'echo "SRE Linux 22.04"
m=$(free -mh | grep Mem:)
echo -n "Memory : "
echo $m | cut -d\' \' -f2

cn=$(cat /proc/cpuinfo | grep \'model name\' | head -n 1 | cut -d \':\' -f2)
echo -n "CPU : "
echo $cn

m=$(df -h | grep /dev/sda)
echo -n "Disk : "
echo $m | cut -d \' \' -f2' > sysinfo

$ hdfs dfs -put  sysinfo  /apps
$ hdfs dfs -cat  /apps/sysinfo | bash  
SRE Linux 22.04
Memory : 7.8G
CPU : Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
Disk : 492G

連線到 gbean

$ hdfs dfs -ls /apps
Found 2 items
drwxr-xr-x   - rbean bigboss          0 2022-07-13 16:23 /apps/sh
-rw-r--r--   2 rbean bigboss        264 2022-07-13 16:25 /apps/sysinfo

gbean 刪除 /apps/sysinfo

$ hdfs dfs -rm /apps/sysinfo
rm: Permission denied: user=gbean, access=WRITE, inode="/apps":bigred:bigboss:drwxrwxr-x

注意 ! 不可刪除 ! 因未授權刪除的權限給 gbean 使用者

執行 hdfs 檔案系統的 /apps/sysinfo

$ hdfs dfs -cat /apps/sysinfo | bash
SRE Linux 22.04
Memory : 2.9Gi
CPU : Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz
Disk : 491G
tags: 資料科技平台