跳到主要內容

發表文章

目前顯示的是有「shell script」標籤的文章

Mount Https Iso at local

Linux有httpfs可以用於mount http iso於本地端,但一直編不出httpfs支援ssl的版本(請參考後記)。後來一個同學分享了httpdirfs給我,嘗試在Ubuntu 20.04.5 LTS上調整一些code且編譯後,就可以連我們自己簽的https server。本篇文章主要用在記錄過程。 Build 執行make編譯會出現以下錯誤,直接調整Makefile移除-fanalyzer後,就可以正常編譯了: cc: error: unrecognized command line option '-fanalyzer' Modify Code 在執行mount https之後,出現以下錯誤: curl_process_msgs: 60 - SSL peer certificate or SSH remote key was not OK 但發現使用合法憑證搭配合法hostname,還有使用http時都沒有問題,所以懷疑是CURL驗證出了什麼問題。文檔內容如下,但加上–insecure-tls是沒有用的: --insecure-tls Disable licurl TLS certificate verification by setting CURLOPT_SSL_VERIFYHOST to 0 最後在src/link.c中,多做了CURLOPT_SSL_VERIFYHOST的設定(原本code是針對CURLOPT_SSL_VERIFYPEER設定為disable), ret = curl_easy_setopt ( curl, CURLOPT_SSL_VERIFYPEER, 0 ) ; ret = curl_easy_setopt ( curl, CURLOPT_SSL_VERIFYHOST, 0 ) ; 改完code重新編譯就成功了。 Execute Command # http . / httpdirfs -f --cache --single-file-mode http: // 10.146.16.150: 8080 / bootimage / driverdisk.iso / opt / mjgoodman / mn...

Linux Shell Script

ShellScript有多強大我不必贅述。我所撰寫的文章都是以前遇到問題所想到的解決方法,也許不是每個做法都很完美,畢竟都是遇到的東西越多,才越能學習到更多更精闢的語法。 如何透過Shellscript去開啟與關閉你的VM?   如何給予一個關鍵字去砍掉對應的Process? 找尋被佔用的Port 替換檔案 量測Process Execution Time Linux AutoLogin 字串取代 如何由PID去找它所佔用的port? Rebind所有的SCSI hard drive nc - netcat to wait for the notification 取得IP Address included ipv4, ipv6 and cable status Bypass invalid options of getopts Mount Https Iso at local 暫存區 grep space 並非所有系統grep都支援\s去偵測空白,可以使用[:space:]或[:blank:]當替代方案。(實測SLES11 grep 2.5.1不支援\s寫法) how-to-find-a-space-in-a-text-using-grep? 確認行數 代表有15行。 > lspci | awk '{ print NR }' 1 2 .. 15 Assign指令結果至變數 使用`號去包起來,以下範例會顯示123。 VAR = ` echo 123 ` echo $VAR 假如指令有問題也要一併導至VAR,可以透過將stderr導向stdout: VAR = ` ff 2 >& 1 ` echo $VAR 抓mac ifconfig | grep -o -E '([[:xdigit:]]{2})(:[[:xdigit:]]{2}){5}' 設DNS Ubuntu很搞怪,不能直接改resolve.conf: systemd-resolve --set-dns=10.146.125.97 --interface enp3s0f0

Get IP Address on linux

Introduction 網路上有許多教學告訴你如何透過ifconfig去取得ip address,而本篇教學主要分享我認為比較通用且簡單的做法。 Get the interface list and check the cable status 取得interface list方法很多種,除了可以透過ifconfig、ip等command外,先前我們是透過cat /proc/net/dev的方式。但我認為透過list /sys/class/net的方法比較簡單且通用: net_base = / sys / class / net /   for dev in ${net_base} * ; do dev_name = ${dev##*/} is_carrier = ` cat ${dev} / carrier ` echo ${dev_name} echo ${is_carrier} done 有幾個部分需要注意的,以eth0為例: dev變數為/sys/class/net/eth0的完整路徑,因此透過${dev##*/}的方式刪除以/前最長的部分,即/sys/class/net/。 /sys/class/net/eth0/carrier如果在interface down的情況下,會出現如下圖錯誤;因此請先up後再做判斷。 Get IPv4 and IPv6 Address 許多教學都是透過ifconfig去達成,由於我們script需要能夠執行於Ubuntu Server的安裝環境下(無法用cut與awk),因此我使用ip command。 # 可在Ubuntu Server 14.04安裝環境下使用 ip addr show | grep -o 'inet [0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+' | grep -o [ 0 - 9 ] . * 如果要指定interface eth0: ip addr show eth0 ipv6比較難寫,我改使用以下方法,將不需要的部分去頭去尾: ip = ` ip addr show eth0 | grep -o 'inet6 .*' ` ip =...

nc - netcat to wait for the notification

Problem 機器A等待著機器B的通知,當接收到通知後,會進行某些工作。 How to? 機器A透過nc啟動4444 port等待通知: #!/bin/bash   result = ` nc -l 4444 ` if [ " $result " == "debug" ] ; then echo "Start to debug." else echo "Ingore to debug." fi 機器B通知機器A開始動作: Socket s = null ; try { s = new Socket ( "192.168.1.110" , 4444 ) ; s. getOutputStream ( ) . write ( "debug" . getBytes ( ) ) ; } catch ( Throwable e ) { e. printStackTrace ( ) ; } finally { Cleaner. close ( s ) ; } 如果機器A允許重複接收指令,可以改用loop方式去等待;如果提供不同功能,可以根據收到的指令做操作。 Reference 8 Practical Linux Netcat NC Command Examples

Rebind所有的SCSI hard drive

Problem 由於USB的Storage有時會比一般SATA的硬碟早被系統載入,而導致USB的Storage為/dev/sda,而其它的則是sdb、sdc等,這造成我們實作某些功能上的困擾。網路上提供的workaroud,像是直接透過uuid指定path;或將要使用項目由sda自動遞增為sdb。這些方法對於做軟體的來說,有著是否能正常取得uuid又或者處理自動遞增複雜度的問題存在。因此我花了一些時間找尋與思考較保險且簡單的解決方法。 註: 由於我們要實作的功能有些限制存在,我無法明講。而這些限制影響了解決方法的自由度,因此我提供的方法僅供需要的人參考。而不同的解法,會隨著支援系統種類需要增加,也許rebind已能解決所有的也不一定。 How to? How to?我認為有幾種可能解法: 別讀取usb_storage module: 不去讀取偵測USB storage的driver不就可以阻止這事情發生嗎? 延遲load usb_storage module: 如果我先偵測了固有的hard drive的driver後,再去偵測USB的部分,不就可以確保USB的storage一定會在後面嗎? reload usb_storage module與hard driver相關的modules: 如果我無法延遲usb_storage載入,那我只要重新再載入去限制順序,不就可以接到第二個方法嗎? Ignore to load 這個方法不適用於你需要其它的USB服務,例如USB CDROM: RHEL5 nousb與nousbstorage參數,此參數在RHEL6與7已被移除。 RHEL6 blacklist參數。 RHEL7 modprobe.blacklist參數。 除了以上方法,從document中得知,應該也可以透過rd.driver.blacklist去指定禁只載入項目,我只試驗過RHEL7是可行的。 Delay load time RHEL6 在RHEL6有driverload參數,讓modprobe前先load你指定的項目。 label linux menu label ^Install Red Hat Enterprise Linux 6 kernel vmlinuz append initrd =initrd.img driverload =ahc...

如何由PID去找它所佔用的port?

Problem 之前 曾寫了一篇找尋被佔用Port的方法,觀望網路上大部分找到的教學也都是在講由port找process的方法。但如果今天我想要知道某一個Process到底用了哪些port該怎麼辦? How to resolve? 平常我在check一個process用了哪些port,我會這樣做: 透過ps去找pid。 透過netstat去找所有使用的port。 看這些port占用的pid是誰。 如果不怎麼要求結果要做些什麼整理的,直接用下面的script就可以看到process與port的對應了。 IFS =$ '\n' pid_list = ( ` ps aux | grep "$1" | awk '{print $2}' ` )   for pid in ${pid_list[@]} ; do netstat -nap | grep " $pid " done tcp 0 0 0.0.0.0: 8080 0.0.0.0: * LISTEN 4437 / java tcp 0 0 0.0.0.0: 8443 0.0.0.0: * LISTEN 4437 / java tcp 0 0 127.0.0.1: 32001 0.0.0.0: * LISTEN 4437 / java tcp 0 0 127.0.0.1: 31001 127.0.0.1: 32001 ESTABLISHED 4437 / java tcp 0 0 127.0.0.1: 32002 0.0.0.0: * LISTEN 4508 / java tcp6 0 0 ::: 5111 ::: * ...

Bypass invalid options of getopts

Problem 我有一隻程式是透過python撰寫,然後透過shellscript去啟動。因為我懶得加功能在python上,所以希望能透過修改shellscript去增加新功能的選項。然而,當我透過getopts去parse輸入參數時,如果少宣告參數在getopts上,程式就會自行停止。本篇文章主要分享pypass的方法。 How to? 預設情況下getopts遇到有問題參數就會停止並顯示無效參數,要避掉這問題解法如下, 在getopts的第一個參數最前面加上:,可以把處理問題流程交給我們自己的腳本。 在?與:處理流程上執行shift,讓parse動作繼續往下。 branch =master test_mode = false while getopts ":b:t" OPT; do case $OPT in b ) branch = " $OPTARG " ;; t ) test_mode = true ;; \? ) shift ;; : ) shift ;; esac done 這樣就可以pypass掉不想處理的項目。 Reference new to Bash - keep getting Illegal option error

ShellScript-字串取代

Problem 一開始的目的是為了取代檔案$FILEPATH中的$target字串為$replace_str,如以下script: cmd = "sed -i 's/ $target / $replace_str /g' $FILEPATH " eval $cmd 但因為$replace_str是一個路徑字串,會包含/(Slash),對sed來說是特殊字元,我們必須在/(Slash)前加一個\(Backslash)。所以我要做的事情就是取代$replace_str中的/為\/。 How to? Method 1 - awk 基本上就是透過gsub這個函式: new_replace_str = ` echo $replace_str | awk '{gsub("/","\\\/",$1);print $1}' ` Method 2 - variable replacement 變數內容取代有兩種寫法: ${變數名稱//舊字串/新字串} 取代所有符合字串 ${變數名稱/舊字串/新字串} 僅取代第一個符合字串 對於處理路徑的問題可以這樣寫: new_replace_str = ${replace_str//\//\\/} ; 後記 sed也可以做到取代檔案內某個字串的效果,可以參考 link 。

ShellScript-Linux AutoLogin

Problem 為了利於測試,先前做過各個不同作業系統的自動登入( link )。隨著測試機逐日增加,為了節省時間與練習shellscript,因此決定寫一個script將設置自動登入的動作給簡單化。但面對不同的Linux,會有不同的自動登入方式,我也很直接的針對不同Distribution使用不同的做法。目前我所支援的作業系統為SLES11、RHEL5、RHEL6、CentOS5、CentOS6。 How to? 確認Linux Distribution 首先我們可以透過/etc/issue去判斷作業系統版本。以下是我收集的資訊: Welcome to SUSE Linux Enterprise Server 10 SP2 Welcome to SUSE Linux Enterprise Server 11 SP2 Red Hat Enterprise Linux Server release 6.0 Red Hat Enterprise Linux Server release 5.6 CentOS release 5.6 CentOS Linux release 6.0 作法是透過grep指令去判斷/etc/issue檔案是否有出現對應的OS Pattern。SLES判斷是否有SUSE;CentOS/RHEL則是判斷開頭字串與主要版本號;其它的顯示不支援。找到對應的Distribution後就呼叫對應的function。這裡設置OS_INFO_FILE變數為$1與將實際操作寫為各個function,主要是為了便於測試,不然系統檔改壞就要DRBL了。 OS_INFO_FILE = $1 if [ "$1" == "" ] ; then OS_INFO_FILE = / etc / issue fi   if grep SUSE $OS_INFO_FILE > / dev / null; then setupAL_SLES elif grep -e "\(CentOS\)\|\(Red Hat\).*5\.*" $OS_INFO_FILE > / dev / null; then setupAL_RHEL5 elif grep -e ...

量測Process Execution Time

今天遇到要驗證Process的Kernel Mode Time與User Mode Time,詢問Kay之後得知運算方式如下: Kernel Mode Time: stime + cstime (/proc/$pid/stat中的field 15與17) User Mode Time: utime + cutime (/proc/$pid/stat中的field 14與16) 從/proc/$pid/stat中取得的time是以jiffies為單位,將jiffies * CLK_TCK就會得到以秒為單位的時間,而最終希望以100 nanosecond呈現。為了方便我驗證,我寫了一段shellscript去做計算並顯示出來: pid = $1   utime_f = 14 cutime_f = 16 stime_f = 15 cstime_f = 17   utime = ` cat / proc / $pid / stat | cut -d " " -f $utime_f ` cutime = ` cat / proc / $pid / stat | cut -d " " -f $cutime_f ` u_mode_time = ` expr $utime + $cutime `   stime = ` cat / proc / $pid / stat | cut -d " " -f $stime_f ` cstime = ` cat / proc / $pid / stat | cut -d " " -f $cstime_f ` k_mode_time = ` expr $stime + $cstime `   clock = ` getconf CLK_TCK `   ns_100 = 10000000 nsc = ` expr $ns_100 / $clock ` # unit: 100 nanosecond echo User Mode Time ` expr $u_mode_time \ * $nsc ` echo Kernel Mode Time ` expr $...