捐血一袋救人一命

江蘇拙政園

江蘇 拙政園

全家福

日本 和歌山城

賞楓之旅

千燈 夕照

水鄉千燈

蘆洲 微風運河

破曉時分

2024年12月12日 星期四

Dragon Quest 5

Dragon Quest V 勇者鬥惡龍5

遊戲攻略概述,整個遊戲分成三階段

  1. 幼兒期5歲~跟著父親帕帕斯王到處冒險
    • 收刮船上物資
    • 聖玫瑰村:先到家門口的井中撿取聖玫瑰石,再到村口旁的農田,找農夫交談(沒撿到聖玫瑰石,會得不到聖原石訊息;沒交談會找不到聖原石),會得到聖原石的訊息,然後進入村中山洞救道具店老闆,調查壓住道具店老闆的石頭,可獲得聖原石(等壯年期可在艾爾赫文找到工匠打磨成聖寶石,名產品之一,可鑲在亨利王子送的音樂盒上)
      小技巧:- 練到 Level 5 以上,學會荷依米治療,且生命至少有 20 點以上(怪物大木鎚會經常出大招),再繼續往下層探險
    • 從阿爾卡帕村與碧安卡一起到勒努爾城解放鬼魂,收集銀質茶具、取得金色寶珠,回到阿爾卡帕村後,殺人豹加入同伴
      小技巧:- 多買些氣味袋,縮短練功時間
      • 大約練到 Level 10 ,就可以很輕鬆打敗鬼魂老大
    • 到妖精之村協助取回春風長笛,獲得櫻花樹枝(名產品之一,沒其他用途)
      小技巧:- 大約練到 Level 15 就可以輕鬆打敗怪物變成的雪之女王
      • 雪之國的城堡外面左邊有寶箱
    • Level 20 到古代遺蹟拯救亨利王子~父親帕帕斯被蓋瑪殺死,主角及亨利被蓋瑪擄去當奴隸
      小技巧:- 多準備一些氣味袋,在古代遺跡中盡快找到帕帕斯,陪同一起練功,帕帕斯生命、醫療法術用不完,而且會幫忙打怪
  2. 青年期15歲~
    • 從大神殿逃出~到修道院,取得木雕女神像(裝備後幸運值上升)
    • 告別瑪麗亞,與亨利一起踏上返鄉歸途
    • 在聖果鎮跟怪物爺爺談話,去神諭之屋買馬車
      小技巧:- 雙六遊戲券別急著去玩,你可以存檔後去玩玩看,瞭解一下這是什麼樣的遊戲,然後直接跳出遊戲,再重新載入
      • 所有遊戲券累積到最後,去暗黑雙六台玩,終點是名人卡,有名人卡以後玩雙六都不用券
      • 最後只要留一張雙六券,用來完成回憶項鏈(名產品之一,沒其他用途)
    • 到聖玫瑰村中山洞取回父親遺物,帕帕斯之劍、帕帕斯的信、天空之劍
      小技巧:有幾隻怪物必須要抓,後面遊戲會比較輕鬆-
      • 史萊姆
      • 史萊姆騎士:對冰系及火系法術有基本抗性,此外能使用多數裝備,例如:斬龍劍(對龍系怪物傷害加倍)、淺眠之劍(對隱藏魔王艾斯塔克很有效)、風雪之劍(對大魔王米爾德拉斯很有效)
      • 雪人:冰系怪物,升級有點慢,等到學會冰雨特技,就可以不花MP打怪,尤其是取得火之戒指時就很好用。
      • 迷你龍:火系怪物,升級有點慢,等到學會火燄氣息,就可以不花MP打怪
      • 邪惡蘋果/青果怪:風系怪物,升等快,可以馬上協助練功,但只能升到20級,所以要搭配其他怪物
    • 到阿爾卡帕村附近練功,在旅店睡兩次,就可以得到安眠枕(名產品之一,戰鬥中使用,會丟向怪物,偶爾會有催眠效果)
    • 到萊茵海特城,從城堡右側搭木閥,進入城門橋下的洞;讓亨利認親~告知國王假太后資訊
    • 到神之塔→再到修道院找修女,瑪麗亞會加入隊伍(有瑪麗亞才能打開神之塔的門)→取得太陽神鏡
    • 到萊茵海特城,在假太后面前使用太陽神鏡,殺掉假太后
      小技巧:有幾隻怪物必須要抓,後面遊戲會比較輕鬆- 殺掉假太后之後,就無法在進入神之塔,所以在殺掉假太后之前,神之塔的寶物要先搜刮完
    • 搭船到波特賽爾密
    • 在波特賽爾密酒店救人
    • 到卡波奇村西邊洞窟,主角身上要放碧安卡的緞帶,戰鬥時使用,給殺人豹聞,即可結束戰鬥,殺人豹會加入隊伍;如果是其他怪物身上放碧安卡的緞帶,只是會退出戰鬥,離開洞穴。
    • 到卡波奇村長家領賞
    • 到魯拉菲爾學習法術
    • 取得魯拉月草
    • 取得魯拉菲爾的地方酒(名產品之一,沒其他用途)
    • 到薩拉波納鎮求親
    • 取得火之戒指
      小技巧:- 多準備些氣味袋,洞窟中有全體復原的神壇,很適合練功
      • 洞中怪物怕冰系法術,記得在萊茵海特城要先抓隻雪人
    • 到深山之村找回碧安卡(在阿爾卡帕2樓露台,老人會透露碧安卡搬到哪去)
    • 帶碧安卡一起去取得水之戒指,如果碧安卡太弱,進山洞前調整隊伍,不要讓碧安卡在隊伍即可,只是樂趣會減少些(少了一個人時不時在耳邊嘮叨 XD)
    • 新娘三選一(碧安卡、狄波拉、芙蘿拉)
      • 碧安卡對話態度感覺像是姊弟
      • 狄波拉對話態度感覺像是主僕
      • 芙蘿拉對話態度感覺像是夫妻
      • 這三個人物的素質影響不大,因為剛結婚加入隊伍時,人物太弱,只能放在馬車中升等,不能放出來戰鬥。
      • 等練的差不多了,又會被魔物擄去、石化
      • 等到主角壯年期後期救回時,人物強度跟不上隊伍,也只能放在馬車中升等。
      • 三位新娘必要的法術都會有
      • 選狄波拉或是芙蘿拉當妻子,魯德曼會在遊戲過程中送些武器、裝甲、錢
    • 獲得紅白包子(名產品之一,不確定還有什麼變化,因為紅白包子的物品代號就有三個!根據網友的說明,包子上面印有不同人像)
    • 跟德魯曼告別,獲得天空之盾
    • 到名產博物館,跟老鬼交談,得到大徽章訊息
    • 特魯帕多爾,有天空之盔的消息,要等兒子長大才能拿走;防具店有沙漠玫瑰的消息,在旅店睡一晚,隔天在城外就可以找到沙漠玫瑰。記得拿兩次沙漠玫瑰,一個要到碧安卡的村子中的水井裡,換溫泉精華素。
    • 然後去徽章王城堡,先跟旅店老闆娘講話,買徽章形巧克力(名產品之一),然後找徽章王談話,再找旅店老闆娘、銀行大叔分別交談,最後出城,到河邊就會看到大徽章,救了史萊姆,它就會把大徽章塞給你,(名產品之一,可以當盾牌裝備)~然後回到名產博物館,跟老鬼對話,成為博物館長
    • 前往齊索特村的山道,在齊索特村洞口跟小孩說話,再回去找齊索特老太太,就會給你齊索特羅盤(名產品之一,使用時會告訴你所在位置)
    • 前往格蘭巴尼亞國,在城堡裡面的右邊,有個小房子,是桑喬的住所,去找他就會帶你上樓找國王。
    • 在二樓左下角酒吧裡的空位,找到一顆怪物象棋,交給最左邊的士兵,就可以獲得怪物象棋(名產品之一,沒其他用途)
    • 取得王家之證~成為國王
    • 老婆被魔物擄走
    • 在大臣房中取得飛天鞋
    • 或者在城堡左上角房間取得怪物象棋(如果被石化後再被兒子女兒救回,就得找皮皮恩了,讓皮皮恩加入隊伍,出城,在回城叫皮皮恩休息,然後去找皮皮恩對話)
    • 救老婆不成~被石化
  3. 壯年期3X歲~
    • 被兒子、女兒救回
    • 臨行前佣人交給主角帕帕斯的遺物-回憶項鏈(名產品之一,沒其他用途,目前是空的,沒畫像)
    • 回母親故鄉艾爾赫文,取得魔毯及魔法鑰匙;把聖原石加工琢磨成聖寶石
    • 前往天空之塔塔頂,取得岩漿法杖
    • 從地下遺跡洞窟前往天空城
    • 前往妖精之村,取得妖精號角
    • 前往妖精之城,回到過去的聖玫瑰村,以發光寶珠換走金色寶珠
    • 返回天空城,操控天空城,飛到波布爾塔的草地降落
    • 前往波布爾塔~打敗蓋瑪、賈貢,取得龍之寶珠、龍之法杖,回天空城救龍王,得到天空之鈴
    • 前往薩拉波納,找德魯曼,德魯曼要求去看神壇封印顏色;再回薩拉波納,士兵叫你去塔裡找德魯曼,然後德魯曼就溜了!只能硬著頭皮打敗普翁!會得到最終鑰匙。
    • 如果老婆不是選碧安卡,跟魯德曼的老婆對話,會給 5000元零用錢…
    • 前往大神殿救老婆,先取得天空之鎧,打敗兩個魔頭,取得生命戒指
    • 前往從艾爾赫文的海中洞窟一直往北走,進入海中神殿,對女神獻上水之戒指、火之戒指、生命戒指,進入魔界,取得賢者之石
    • 前往賈漢納,練功
    • 前往暗黑雙六~取得名人卡
    • 前往各地雙六
    • 前往邪惡山脈,打敗蓋瑪,他會經常麻痺敵人,所以每個人身上要準備一些滿月草,最好還會奇阿里克法術。最後打敗大魔王米爾德拉斯
    • 前往妖精之城,從二樓右翼畫中,進入過去的艾爾赫文,先去長老樓上閣樓,跟士兵對話,再去旅店跟老闆對話,再去找閣樓士兵,使用雙六遊戲券,士兵就會離開;接著去工匠室,跟帕帕斯及畫師對話,離開艾爾赫文回到現實;跟妖精之城一樓右後方歷史學者對話,再去妖精之村一樓圖書館裡的妖精對話,取得妖精的羽毛筆;連同象牙墨水一起帶在身上,再回到妖精之城二樓右翼畫中,進入過去的艾爾赫文,跟帕帕斯對話,把妖精的羽毛筆以及象牙墨水一起借給帕帕斯。再去瑪薩的房間跟所有人對話,離開過去的艾爾赫文,再從畫中進入過去的艾爾赫文,然後去工匠房找到畫師,取回妖精的羽毛筆及象牙墨水(此時回憶項鏈已自動完成畫像)
    • 前往邪惡山脈南面的沼澤迷宮(沒有打敗一次大魔王之前,是無法進入的)
    • 前往迷之雙六,最終獎品是迷你怪物艾克塔斯,連帶可以去找普翁加入。
    • 取得暗黑獎盃(名產品之一,沒其他用途)

貼心提醒:

  1. 青年期之後,古代遺跡就完全沒怪物了,所以建議在幼童期,多多打怪,這樣怪物圖鑒才會有記錄。
  2. 青年期在打敗萊茵海特的假太后之後,神之塔就無法再進入(因為瑪麗亞會跟亨利一起脫隊結婚),所以寶物一定要拿完,怪物也要多打。
  3. 到壯年期之後,萊茵海特的地下通道也會無法進入(木筏會消失,皇宮中庭樓梯會消失),記得寶物要拿完
  4. 在青年期要救老婆之前,一定要記得先取得怪物象棋;之後要取得怪物象棋,請將士兵皮皮恩帶出去,再留下來,然後去找他對話,他就會給你怪物象棋了。
  5. 玩雙六最好是等拿到暗黑獎盃之後,因為某些格子會永久降主角的基本屬性。
  6. 玩雙六最好身上多帶些錢,因為某些格子是道具店,可以買到特別的裝備!例如:星降手環、破壞鐵球(攻擊全體的最強武器,想想看一隊四人全部都裝備破壞鐵球,一輪攻擊將近600點)等。

ADB Send Short Message

使用安卓手機搭配 ADB 發送簡訊

操作程序:

  1. 安裝 ADB 工具
  2. 手機設定啟用開發人員選項
  3. 手機啟用 USB 偵錯模式
  4. 使用 USB 線,將手機連接電腦,並在手機上允許電腦進行偵錯
  5. 開啟終端機視窗
  6. 執行發送命令程式
ADB shell am start -a android.intent.action.SENDTO -d sms:<TARGET_PHONE_NUMBER> --es sms_body "<SMS_CONTENT>" --ez exit_on_sent true

注意:

  • 網路上流傳的 keyevent 其實就是在移動一個看不見的鼠標,將鼠標移動到簡訊發送鈕上,再送出 keyevent 66 (Enter)
  • 這會因為手機品牌型號不同,簡訊程式發送鈕的位置佈局不同,甚至同一個目標門號有歷史紀錄,都導致 keyevent 執行的代碼與次數不同

解決方法:

  1. 手機操作到發送簡訊的畫面
  2. 終端機執行 ADB Dump UI 結構的指令
    adb shell uiautomator dump
    
  3. 將 UI 結構的 XML 檔案拉回電腦上
    adb pull /sdcard/window_dump.xml
    
  4. 從 XML 檔案中,找到發送鈕的資訊
  5. 改用 adb shell input tap 座標方式發送

以我的手機為例:

  1. Dump UI XML
adb shell uiautomator dump

输入图片说明
2. Pull File to Windows,檔案會存在當前目錄下

adb pull /sdcard/window_dump.xml

输入图片说明
3. 打開 XML 檔案,找到發送鈕的 resource-id,其中就包含左上右下的座標
输入图片说明
4. 計算一下大約要 tap 的座標

915 + (1047 - 915) / 2 = 981
2116 + (2180 - 2116) / 2 = 2148
  1. 執行點擊座標的程式
adb shell input tap 981 2148

備註:

  • XML 檔案包含簡訊應用程式的名稱,我的手機應用程式名稱是 com.google.android.apps.messaging

Reference:

2024年11月25日 星期一

GoAccess

GoAccess - Visual Web Log Analyzer

  • 這是一個支援各種 Web Service Log 的分析程式,內建了 Apache & Nginx 的 Log 格式設定
  • 也可以支援 自訂 Log 格式
  • Geo Location 需要搭配 MAXMind GeoLite2 Database,才會有訪客地域分析
  • 手動自行編譯,才能使用完整的功能

安裝方式介紹

下載原始碼,自行編譯

  • 這裡並沒有補上相依的函式庫,請自行編譯時,查看錯誤訊息,下載相關函式庫工具一起編譯
wget https://tar.goaccess.io/goaccess-1.9.3.tar.gztar -xzvf goaccess-1.9.3.tar.gzcd goaccess-1.9.3/./configure --enable-utf8 --enable-geoip=mmdb --enable-geomapmakemake install

透過 apt 安裝

  • 沒有 Geo Location World Map
wget -O - https://deb.goaccess.io/gnugpg.key | gpg --dearmor | sudo tee /usr/share/keyrings/goaccess.gpg >/dev/nullecho "deb [signed-by=/usr/share/keyrings/goaccess.gpg arch=$(dpkg --print-architecture)] https://deb.goaccess.io/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/goaccess.listsudo apt-get updatesudo apt-get install goaccess
  • 用程式及設定檔路徑:/etc/goaccess/goaccess.conf/usr/bin/goaccess

使用 GitHub 版本編譯安裝

# 從 GitHub 下載原始碼(這裡環境使用 Ubuntu)
git clone https://github.com/allinurl/goaccess.gitcd goaccess
# 安裝相依的套件
sudo apt install autopoint build-essential gettext libmaxminddb-dev libncursesw5-dev -yautoreconf -fi
# 啟用 GeoLite2 資料庫,並啟用 Geo Location Map
./configure --enable-utf8 --enable-geoip=mmdb --enable-geomap
# 進行編譯
make
# 進行安裝
make install
  • 應用程式及設定檔路徑
    • /usr/local/etc/goaccess/goaccess.conf/usr/local/bin/goaccess

設定

Log 時間、日期與欄位格式

  • 不管是 apt 套件版,或是 GitHub 編譯版,預設設定檔都一樣,time-format, date-format, log-format, 都沒有設定,所以不能直接使用 (當然也可以在命令列使用參數指定這些格式)
  • 以下為 nginx 的設定格式
time-format %H:%M:%Sdate-format %d/%b/%Ylog-format %h %^[%d:%t %^] "%r" %s %b "%R" "%u"

指定 Geo IP 地理資料庫

  • geoip-database 的設定如下
geoip-database /usr/share/GeoIP/GeoLite2-ASN.mmdbgeoip-database /usr/share/GeoIP/GeoLite2-Country.mmdbgeoip-database /usr/share/GeoIP/GeoLite2-City.mmdb

命令行直接使用參數指定格式

goaccess ~/tmp/access_portal.log.2 --log-format='%h %^ %e [%d:%t %^] "%r" %s %b "%R" "%u"' --date-format=%d/%b/%Y --time-format=%T -o /var/www/Subs/stats/index.html

範例

處理 AD 所有相關紀錄

zcat -f /var/log/nginx/access_AD.log* | /usr/local/bin/goaccess \--enable-panel=GEO_LOCATION \--enable-panel=MIME_TYPE \--enable-panel=CACHE_STATUS \--enable-panel=VISIT_TIMES \--enable-panel=VISITORS \--enable-panel=REFERRERS \--enable-panel=KEYPHRASES \--enable-panel=CACHE_STATUS \--enable-panel=REQUESTS \--enable-panel=REQUESTS_STATIC \> /home/tom/ad.html
  • zcat 會自動處理 .gz 檔案的解壓縮
  • 如果 Log 檔案很大,又經過多日的 Log Rotate, goaccess 一次處理起來,會很耗用系統資源

2024年7月18日 星期四

以 Windows 內建的 AppLocker 來管制使用者執行/安裝應用程式

AppLocker 是一個用來管制電腦可以運行的程式、Installer(.msi)、指令碼(.bat, .cmd, .vbs, .ps1, .js,...)、DLL、封裝的應用程式(.app, .appx)的服務。 

它從 Windows Server 2008 R2/Windows 7 就已經存在,但是卻很少人使用它。

其實搞懂它之後,它就是免費強大的資安管理系統!

要使用 AppLocker,有一個必要條件,Windows 10 版本需要更新到 22H2 版本以後,不然即使設定好相關的政策與服務,AppLocker 也不會生效!

AppLocker 要依靠 AppIDSvc 服務(Application Identity),看名字就知道是用來識別應用程式的服務 。

但是,在Windows 10 的服務管理,卻無法設定該服務於開機時自動啟動! 
網路上多是叫你用 sc.exe 來設定該服務
sc config appidsvc start=auto
或是去修改機碼
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AppIDSvc] "Start"=dword:00000002
其實 AppIDSvc 是由 AppID 服務控制,只要設定 AppID 開機自動啟動,AppIDSvc 開機就會自動啟動(但是服務啟動類型仍顯示為手動啟動) 你可以使用
sc config appid start=auto
或是使用 Powershell
Set-Service -Name AppID -Startup Automatic


注意:這個 AppID 在服務裡是找不到的!所以你沒辦法用服務管理 GUI 來維護。(個人猜測,本來是要在 AD 環境管理的;但是我是沒有AD的環境,只能這樣處理)

當你重新開機,讓 AppID & AppIDSvc 服務啟動之後

你可以透過 c:\windows\system32\secpol.msc 啟動 本機安全性原則管理程式。

安全性原則 > 應用程式控制原則 > AppLocker

它分成四大類可以運行的程式

  1. 可執行檔規則
  2. Windows Installer 規則
  3. 指令碼規則
  4. 已封裝的應用程式規則

這四項當中,如果都沒有任何規則時,預設是全部允許執行!

但是,當你設定有任何一個規則,預設是全部不允許!所以你要做的就是設定哪些程式允許被執行!


要讓所有人可以正常運行Windows基本功能,請在這四大項,建立預設規則(D)

 

另外,當你要設定拒絕規則時,請不要使用內建的 Users 群組名稱,這會造成連管理者都被拒絕執行!請務必自行建立一個新群組名稱,然後把使用者帳號加入群組,然後設定該群組拒絕執行。


AppLocker

Powershell cmdlet for AppLocker

Docker Engine API

Docker Engine API

Docker 的架構

  • 下圖是 Docker 官方的架構圖
  • 由圖可知,Docker Client 與 Docker Host 是可以分開的
  • 而我們一般運行 Docker,Client & Host 是同一台伺服器
    image.png
  • Docker Engine 提供了 Web API,讓你可以使用慣用的程式語言來控制 Docker Engine,甚至 Docker Container Apps 的數量(Scale Up/Down)
  • 另外,Docker Engine 也提供了 SDK for Go & Python,熟悉這兩種語言的人,可以直接使用 SDK
  • Docker Engine API 是 RESTful API,你可以很輕鬆地使用 wget, curl, powershell, 或是你慣用的程式語言來存取它。
  • 要使用 Docker Engine API 之前,必須先知道你的 Docker Engine 版本所使用的 API 版本

查詢 Docker API 版本可以使用以下命令

docker version

image.png

啟用 Docker Engine API

Docker Engine API 預設是沒有啟動的,必須自行設定,設定步驟如下

  1. 開啟遠端 Docker Host 上的 Docker Service 設定檔
# 以 systemctl 讀取服務設定
# 第一行是設定檔路徑檔名
# 將第一行的註解符號去除掉,得到完整路徑檔名
# 存入環境變數
DOCKER_SERVICE_CONF_FILE=$(systemctl cat docker.service | head -n 1 | sed 's/^#\s//g')
vi ${DOCKER_SERVICE_CONF_FILE}

# vi /usr/lib/systemd/system/docker.service
  1. 修改其中 ExecStart 的命令,增加 -H tcp://0.0.0.0:2375 並存檔。
    image.png

  2. 然後讓 systemd 重新載入 Daemon 相關設定檔,然後重新啟動 Docker

# 讓 systemd 重新載入 Daemon 設定檔
sudo systemctl daemon-reload
# 重新啟動 Docker Daemon
sudo systemctl restart docker
# 檢查 Docker Service 狀態
sudo systemctl status docker

如果有正常啟動 docker daemon 會看到如下圖

image.png

  1. 檢查 Docker 是否有監聽 2375 Port
sudo lsof -i -P -n | grep dockerd

image.png

sudo ss -tulpn | grep dockerd

image.png

以上就完成了啟用 Docker Engine API


Docker Engine API v1.43 簡單列舉容器相關操作

查詢 Container 資訊

Method: GET
http://{docker_host_ip}:2375/containers/json

參數 說明
all boolean,預設值為 false/0,表示只回傳正在運行的容器資訊;all=true/1,表示回傳所有容器資訊;注意這裡數值的布林值,與Python相同,只有0代表 false,其他數值,不管正負,都代表true
limit integer,回傳最近幾個Container的資訊,包含沒有在運行的容器
size boolean,預設值為 false,回傳資訊增加容器大小
filters string,設定篩選容器的條件

可用的 filters

參數 說明
ancestor 指定 “ancestor”: [“image_name”:“image_tag”]
before 指定 container_id 或 container_name之前的容器
expose 指定 expose port
exited 指定 container exit code
health 指定狀態:starting, healthy, unhealthy, none
id 指定 Container ID
isolation 指定隔離狀態:default, process, hyperv;Windows Daemon Only
label 指定 {“label”:[“key”]} 或是 {“label”:[“key=value”]}
name 指定Container Name
network 指定 network_id 或 network_name
publish 指定 port/proto 或 startport-endport/proto
since 指定 container_id 或 container_name之後的容器
status 指定特定狀態的容器:created, restarting, running, removing, paused, exited, dead
volume 指定volume_name 或 volume_id

範例:

curl http://192.168.13.161:2375/containers/json?all=1
curl http://192.168.13.161:2375/v1.43/containers/json?filters={"ancestor": ["nginx:latest"]}
curl http://192.168.13.161:2375/containers/json?filters={"label":["CallFrom=Powershell"]}

查詢指定的 Container 資訊

Method: GET

http://{docker_host_ip}:2375/containers/[container_id | container_name]/json

查看 Container 內部運行的程式

Method: GET

http://{docker_host_ip}:2375/containers/[container_id | container_name]/top

查看 Container 運行的 Log

Method: GET

http://{docker_host_ip}:2375/containers/[container_id | container_name]/logs

查看 Container 內部被異動的檔案/目錄

Method: GET

http://{docker_host_ip}:2375/containers/[container_id | container_name]/changes

匯出 Container 並下載

Method: GET

http://{docker_host_ip}:2375/containers/[container_id | container_name]/export

持續回傳容器運行資源狀態(JSON)

Method: GET

http://{docker_host_ip}:2375/containers/[container_id | container_name]/stats

建立容器(注意:容器只有建立,並沒有運行)

Method: POST

http://{docker_host_ip}:2375/container/create
網址參數 說明
name string,必須符合正規式 ^/?[a-zA-Z0-9][a-zA-Z0-9_.-]+$

Header請指定 “Content-Type: application/json”

Body JSON 簡單列舉參數如下

參數名稱 說明
Env Array of Strings,指定環境變數及值
Cmd Array of Strings,指定容器啟動時,要執行的命令
Image string,指定容器要使用的 Image Name 以及 Tag
Volumes 指定掛載的磁碟
WorkingDir 指定命令要在哪個目錄下運行
Labels 指定 Key/Value 的 Metadata
HostConfig 設定網路相關資訊,例如:Port Mapping

範例:

使用 bash shell curl 建立 Container

curl -X POST -H "Content-Type: application/json" \
-d '{"Image": "nginx:latest", "ExposedPorts": { "80/tcp": {} }, "HostConfig": { "PortBindings": { "80/tcp": [{ "HostIp": "", "HostPort": "9001" }] } } }' \
http://192.168.213.214:2375/containers/create

使用 Powershell 跑迴圈,建立三個 Container:web01, web02, web03,分別使用 Port 9001, 9002, 9003,並啟動這三個Container

$head = @{ 'Content-Type' = 'application/json' }

$Port = 9000
For($i=1; $i -le 3; $i++){
    $Port++
    $json  = "{""Image"": ""nginx:latest"", "
    $json += """ExposedPorts"": { ""80/tcp"": {} }, "
    $json += """HostConfig"": { ""PortBindings"": { ""80/tcp"": [{ ""HostIp"": ""0.0.0.0"", ""HostPort"": ""$Port"" }] } }, "
    $json += """Labels"" : {""CallFrom"":""Powershell""} }"

    # Create Container
    Invoke-RestMethod -Method POST -Uri ("http://192.168.13.161:2375/containers/create?name=web{0:d2}" -f $i) -Headers $head -Body $json
    # Start Container
    Invoke-RestMethod -Method POST -Uri ("http://192.168.13.161:2375/containers/web{0:d2}/start" -f $i) -Headers $head
}

啟動執行容器(Start)

Method: POST

http://{docker_host_ip}:2375/containers/[container_id | container_name]/start

停止運行容器(Stop)

Method: POST

http://{docker_host_ip}:2375/containers/[container_id | container_name]/stop

重新啟動執行容器(Restart)

Method: POST

http://{docker_host_ip}:2375/containers/[container_id | container_name]/restart

傳送 POSIX signal 給容器(Kill)

Method: POST

http://{docker_host_ip}:2375/containers/[container_id | container_name]/kill?signal=[SIGNAL_STRING | SIGNAL_CODE]

變更容器名稱(Rename)

Method: POST

http://{docker_host_ip}:2375/containers/[container_id | container_name]/rename?name=[new_container_name]

刪除容器名稱(Remove)

Method: DELETE

http://{docker_host_ip}:2375/containers/[container_id | container_name]

以上,當你使用錯誤的 Method 時,會顯示 page not found 錯誤訊息

image.png

參考資料

Configure remote access for Docker daemon
Docker Engine API (1.43)
Docker Engine API version history
Develop with Docker Engine SDKs

docker config

docker config

  • 這個命令是用在 Docker Swarm 環境下
  • 你可以將你的應用程式容器需要的靜態檔案/設定檔,透過 docker config create 存到 Manager Node 上。
  • 當你的應用程式容器在 Worker Nodes 上部署運行時,可以將這些 config 檔案掛載到容器之中
  • 它跟 Volume 的差異,在於 Volume 的掛載是無法跨 Nodes,除非每個 Nodes 都去掛載網路磁碟(smb/nfs/…)

指令表

指令 Description 說明
docker config create Create a config from a file or STDIN 從 STDIN 或是應用程式設定檔來建立 config
docker config inspect Display detailed information on one or more configs 顯示 config 的詳細資訊(其中包含檔案被base64編碼的內容)
docker config ls List configs 條列 Manager Node 上的 config
docker config rm Remove one or more configs 刪除指定的 config

用實例離說明:

部署簡單的 php 程式到 Worker Node web

  1. 建立簡單的 php 程式檔案作為首頁 index.php,用來驗證部署結果
<?php
// 獲取伺服器的 IP 地址
$server_ip = $_SERVER['SERVER_ADDR'];

// 顯示在網頁上
echo "伺服器的 IP 地址是: " . $server_ip;

phpinfo()
?>
  1. 建立 apache 虛擬主機設定檔 ~/000-default.conf
<VirtualHost *:80>
    ServerAdmin webmaster@official.company.com
    ServerName official.company.com
    DocumentRoot /var/www/html

    <Directory /var/www/html>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
  1. 以 apache 虛擬主機設定檔 000-default.conf,在 Docker Swarm Manager Node 上,建立 config
docker config create apache_vhost ./000-default.conf
  1. 列出 config,確認一下
docker config ls

image

  1. 檢查一下 apache vhost config 詳細資訊,你會發現,設定檔內容以 base64 編碼,存在 Data 中
docker config inspect apache_vhost

image

  1. 驗證一下apache_vhost config內容
docker config inspect apache_vhost | jq -r '.[0].Spec.Data' | base64 --decode

image

  1. 驗證一下 index.php config內容
docker config inspect official_homepage | jq -r '.[0].Spec.Data' | base64 --decode

image

  1. 編寫 docker-compose.yml
version: '3.8'

services:
  php_apache:
    image: php:7.1-apache
    deploy:
      replicas: 1
      placement:
        constraints: [node.labels.server == web]
    configs:
      - source: official_homepage
        target: /var/www/html/index.php
        uid: '33'
        gid: '33'
        mode: 0444
      - source: apache_vhost
        target: /etc/apache2/sites-available/000-default.conf
    networks:
      - my_network

configs:
  official_homepage:
    external: true
  apache_vhost:
    external: true

networks:
  my_network:
    driver: overlay
  1. 執行 odcker stack deploy 進行部署
docker stack deploy -c docker-compose.yml official_homepage

image
10. 檢查一下,看看 config 是不是都被容器掛載到對應的路徑

docker ps -a
docker exec -it 6476ac33e359 cat /var/www/html/index.php
docker exec -it 6476ac33e359 cat /etc/apache2/sites-available/000-default.conf

image

  • 從上圖可以看到, php:7.1-apache 被部署到 server 標籤為 web 的 node (lab2)
  • index.php 與 000-default.conf 也都被掛載到正確的路徑下了

2024年7月1日 星期一

Linux 上常用的打包壓縮軟體

Linux 上常見的打包、壓縮軟體

  • tar:(Tape Archive)是一個用於檔案打包的工具,最早用於將多個檔案和目錄打包成一個檔案,便於在磁帶等存儲設備上進行備份和傳輸。
  • gzip:使用 DEFLATE 算法,基於 LZ77 和霍夫曼編碼。
  • bzip2:使用 Burrows-Wheeler 變換和 Run-Length Encoding (RLE) 算法,並結合霍夫曼編碼。
  • xz:使用 LZMA(Lempel-Ziv-Markov chain algorithm)算法,這是一種高度優化的壓縮算法,提供了非常高的壓縮比。

要注意的是,tar 只是打包工具,將多個檔案目錄屬性擁有者ID 等資訊打包成一個 tarball File,本身並沒有壓縮

所以使用 tar,會搭配 gzip, bzip2, 或是 xz 等壓縮工具,來節省空間或是傳書時間

壓縮比:gzip < bzip2 < xz
壓縮速度:gzip > bzip2 > xz
解壓縮速度:gzip > bzip2 > xz
資源用量:gzip < bzip2 < xz

雖然 7z & rar 都有 for Linux 版本,不過在 Linux 上並不流行

tar 搭配 gzip 打包壓縮

tar -zcvf archive.tar.gz /path/to/directory ...

有的人會將 archive.tar.gz 直接命名為 archive.tgz

tar 搭配 bzip2 打包壓縮

tar -jcvf archive.tar.bz2 /path/to/directory ...

注意:參數 j 是小寫

tar 搭配 xz 打包壓縮

tar -Jcvf archive.tar.xz /path/to/directory ...

注意:參數 J 是大寫


常用參數意義

參數 說明
c Create archive
v Verbosely
f use archive file or device ARCHIVE
t List all files in archive
x Extract files from archive
A append tar files to an archive
d find differences between archive and file system
r append files to the end of an archive
u only append files newer than copy in archive

接下來,搭配 ssh,進行遠端管理

命令遠端伺服器壓縮資料

ssh user@box tar zcvf - /dir1/ > /destination/file.tar.gz

將 tar 打包輸出的結果,透過 Pipe 傳給 gzip,並指定 gzip 壓縮程度

ssh user@box 'cd /dir1/ && tar -cf - file | gzip -9' >file.tar.gz

壓縮本機檔案,然後透過 SSH 傳送到遠端伺服器保存

tar zcvf - /wwwdata | gzip | ssh user@dumpserver.nixcraft.in "cat > /backup/wwwdata.tar.gz"

tar 打包壓縮 > gpg加密 > ssh 傳送到遠端主機 cat 輸出成檔案

tar zcf - /data2/ | gpg -e | ssh vivek@nas03 'cat - > data2-dd-mm-yyyy.tar.gz.gpg'

如果遠端伺服器需要特權,ssh 加上 -t 參數,使用 sudo

tar zcvf - /wwwdata | ssh -t vivek@192.168.1.201 "sudo cat > /backup/wwwdata.tar.gz"

命令遠端伺服器壓縮檔案,並傳送到本機目前路徑

cd /path/local/dir/ && ssh vivek@server1.cyberciti.biz 'tar zcf - /some/dir' | tar zxf -

使用 dd 指令備份硬碟 /dev/sdvf 到遠端

dd if=/dev/sdvf | ssh backupimg@vpc-aws-mumbai-backup-001 'dd of=prod-disk-hostname-sdvf-dd-mm-yyyy.img'

從遠端備份硬碟資料還原到本地端

ssh backupimg@vpc-aws-mumbai-backup-001 'dd if=prod-disk-hostname-sdvf-dd-mm-yyyy.img' | dd of=/dev/sdvf

使用 SCP 備份,遇到連結或是特殊裝置路徑就會失敗,可以使用 tar 來備份

ssh vivek@nuc-box 'tar czf - /home/vivek' | tar xvzf - -C /home/vivek
cat my-data.tar.gz | ssh user@server1.cyberciti.biz "cd /path/to/dest/; tar zxvf -"

顯示壓縮進度條

cd /dir/to/backup/ && tar zcf - . | pv | ssh vivek@server1.cyberciti.biz "cat > /backups/box42/backup-dd-mm-yyyy.tgz"

2024年6月28日 星期五

Windows 沙箱環境設定檔

沙箱環境設定檔 Sample

將XML 內容存成副檔名為 ,wsb 設定檔,點擊設定檔,就可以按照設定開啟沙箱

<!-- 副檔名 .wsb -->
<Configuration>
<!-- 設定是否使用獨立顯卡晶片 -->
<VGpu>Default</VGpu>
<Networking>Default</Networking>
<!-- 將本機網路對應到沙箱 -->
<MappedFolders>
	<MappedFolder>
		<!-- 本機路徑 ->>
		<HostFolder>D:\Downloads\Portable Apps</HostFolder>
		<!-- 是否設定唯讀 -->
		<ReadOnly>true</ReadOnly>
	</MappedFolder>
</MappedFolders>
<!-- 啟動沙箱時,要執行的程式 -->
<LogonCommand>	
	<Command>explorer.exe C:\Users\WDAGUtilityAccount\Desktop\Portable Apps\4K Video Downloader Portable v4.12.5.3670</Command>
	<Command>explorer.exe C:\Users\WDAGUtilityAccount\Desktop\Portable Apps\Musify\Musify.exe</Command>
</LogonCommand>
</Configuration>

Windows電腦認證管理員

Windows認證管理員

控制台 > 使用者帳戶 > 認證管理員

不知何時,Windows Update 之後,原先儲存的遠端桌面密碼都沒用了,每次登入都要手動輸入密碼,真的很煩!
使用 cmdkey 指令去查詢,會發現原先儲存的密碼類型,都變成網域密碼,微軟真的很雞婆

讀取目前所有遠端桌面(Terminal Service)的認證清單,並全部移除

$(cmdkey /list:TERMSRV/*) | Where-Object { $_ -match "目標: " } | ForEach-Object {
    $target = $_
    $target = $target -replace "目標: ","" -replace " ",""
    (cmdkey /delete:$target)
}

重新用一般標準方式儲存,類型會是標準

cmdkey /generic:TERMSRV/[IP] /user:[ACCOUNT] /pass:"[PASSWORD]"

讀取目前遠端桌面所有認證資訊

$Patten = "目標: |類型: |使用者: "
$List = @()
$Info = $(cmdkey /list:TERMSRV/*) | Select-String -Pattern $Patten 
For ($i=0; $i -le $Info.Count; $i+=3){
    $List += New-Object -TypeName PSOBject -Property @{
        "Target" = $Info[$i] -replace "\s+目標:\s+",""
        "Type" = $Info[$i+1] -replace "\s+類型:\s+",""
        "User" = $Info[$i+2] -replace "\s+使用者:\s+",""
    }
}
$Domain = $List | Where-Object { $_.Type -eq "網域密碼" }
If ($Domain.Count -eq 0){
    $List | Sort-Object -Property Target
}Else{
    ForEach($Key in $Domain){
        (cmdkey /delete:$Key.Target)
    }
}

2024年6月26日 星期三

HTTP Status Code

HTTP Status Code

狀態碼 說明 類別
100 Continue 請求者應繼續進行請求
101 Switching Protocols 服務器根據請求切換協議
102 Processing (WebDAV) 服務器已經收到並正在處理請求,但無響應可用
200 OK 請求成功
201 Created 請求成功並且資源已被創建
202 Accepted 請求已接受,但尚未處理完成
203 Non-Authoritative Information 請求成功,但返回的元數據可能來自第三方源
204 No Content 請求成功但無內容返回
205 Reset Content 請求成功,要求重置文檔視圖
206 Partial Content 服務器成功處理了部分 GET 請求
207 Multi-Status (WebDAV) 返回多個資源的狀態
208 Already Reported (WebDAV) DAV 之前已經枚舉的成員,不需要再次列出
226 IM Used 伺服器完成了對資源的 IM(instance-manipulations)請求
300 Multiple Choices 請求的資源有多個表示
301 Moved Permanently 永久重定向:HTTP 301 狀態碼表示資源已永久移動到新的 URL,未來的請求應該使用新的 URL
緩存行為:瀏覽器和搜索引擎會更新資源的 URL 並緩存這個重定向,未來的請求將自動使用新 URL
SEO:對於搜索引擎優化(SEO),301 重定向將權重轉移到新的 URL 上,這有助於保持網站的排名
302 Found 臨時重定向:HTTP 302 狀態碼表示資源臨時移動到新的 URL,未來的請求應該仍使用原始 URL。
緩存行為:瀏覽器和搜索引擎通常不會緩存這個重定向,未來的請求仍然會訪問原始 URL。
SEO:對於 SEO,302 重定向不會將權重轉移到新的 URL 上,因為它被認為是臨時的。
303 See Other 請求的資源可在其他 URI 上找到,應使用 GET 方法獲取
304 Not Modified 資源未修改,可以使用緩存版本
305 Use Proxy 請求應通過代理訪問資源
307 Temporary Redirect 暫時重定向:HTTP 307 表示這個重定向是臨時的。未來請求仍然應該使用原始 URL。
保持方法和正文:與 302 Found 狀態碼不同,307 明確要求客戶端在重定向時保持原始的 HTTP 方法和請求正文。例如,如果原始請求是 POST,重定向後仍然是 POST
308 Permanent Redirect 永久重定向:HTTP 308 表示這個重定向是永久的。未來的請求應該使用新的 URL。
保持方法和正文:308 與 301 Moved Permanently 類似,但明確要求客戶端在重定向時保持原始的 HTTP 方法和請求正文。例如,如果原始請求是 POST,重定向後仍然是 POST。
400 Bad Request 服務器無法理解請求
401 Unauthorized 未經身份驗證
402 Payment Required 保留將來使用
403 Forbidden 服務器拒絕請求
404 Not Found 資源未找到
405 Method Not Allowed 請求方法不被允許
406 Not Acceptable 請求的資源的內容特性無法滿足請求頭中的條件
407 Proxy Authentication Required 需要代理身份驗證
408 Request Timeout 請求超時
409 Conflict 請求與資源的當前狀態發生衝突
410 Gone 資源已被永久刪除
411 Length Required 需要有效的內容長度標頭
412 Precondition Failed 先決條件失敗
413 Payload Too Large 請求負載過大
414 URI Too Long 請求 URI 過長
415 Unsupported Media Type 不支持的媒體類型
416 Range Not Satisfiable 請求範圍不符合可用範圍
417 Expectation Failed 服務器未能滿足請求頭的期望值
418 I’m a teapot HTCPCP/1.0 錯誤代碼
421 Misdirected Request 請求導向錯誤
422 Unprocessable Entity (WebDAV) 語義錯誤,無法響應
423 Locked (WebDAV) 資源被鎖定
424 Failed Dependency (WebDAV) 由於之前的請求失敗,當前請求失敗
425 Too Early 服務器拒絕處理可能被重放的請求
426 Upgrade Required 需要切換協議
428 Precondition Required 要求請求附帶前置條件
429 Too Many Requests 請求過多
431 Request Header Fields Too Large 請求頭字段過大
451 Unavailable For Legal Reasons 因法律原因不可用
500 Internal Server Error 服務器內部錯誤
501 Not Implemented 服務器不支持實現請求的方法
502 Bad Gateway 無效的響應
503 Service Unavailable 服務器不可用
504 Gateway Timeout 網關超時
505 HTTP Version Not Supported 不支持的 HTTP 版本
506 Variant Also Negotiates 內部配置錯誤
507 Insufficient Storage (WebDAV) 存儲空間不足
508 Loop Detected (WebDAV) 檢測到循環
510 Not Extended 需要進行擴展
511 Network Authentication Required 需要網絡身份驗證

狀態碼 說明 重定向類型 緩存行為 請求方法 使用場景
301 Moved Permanently 永久重定向 瀏覽器和搜索引擎會更新 URL 並緩存重定向 可能改變方法為 GET(取決於瀏覽器) 當資源永久移動到新位置,應用於 SEO 轉移權重的情況,例如網站遷移或永久更改資源 URL。
302 Found 臨時重定向 瀏覽器和搜索引擎通常不會緩存重定向 可能改變方法為 GET(取決於瀏覽器) 當資源臨時移動到新位置或需要臨時重定向,用於短期的資源變更或 A/B 測試。
307 Temporary Redirect 臨時重定向 瀏覽器和搜索引擎通常不會緩存重定向 保持原請求方法 當需要臨時重定向且必須保持請求方法(例如 POST),用於臨時服務器變更,或維護期間。
308 Permanent Redirect 永久重定向 瀏覽器和搜索引擎會更新 URL 並緩存重定向 保持原請求方法 當資源永久移動到新位置且必須保持請求方法,適用於 API 的永久變更,避免方法變更影響。

總結:

  • 使用 301 或是 308 永久重定向,主要是讓搜尋引擎SEO更新資料、瀏覽器緩存;但是要注意 301 會造成 Request Method 變動
  • 使用 302 或是 307,則是臨時性的變動,例如伺服器維護期間,暫時重新導向,或是負載平衡。瀏覽器不會緩存,也不影響搜尋引擎的 SEO;但是要注意 302 也會造成 Request Method 變動

2024年6月25日 星期二

Reset Synology Gitlab Root Password

重設 Synology Gitlab root 管理者密碼

從 群暉 Synology NAS 套件中心安裝的 Gitlab,與 Gitlab 官方文件不太一樣

  • Rake是一個工具程式,藉由讀取叫做Rakefile的檔案來執行任務腳本,而這些任務腳本就是所謂的task。
    bundle exec rake -T 可以查看 Task List

使用 rake

gitlab-rake 改成 rake,而且必須透過 bundle exe 來執行

docker exec -it synology_gitlab bash
bundle exec /home/git/gitlab/bin/rake "gitlab:password:reset"
(in /home/git/gitlab)
Enter username: 請輸入使用者帳號
Enter password:
Confirm password:
Password successfully updated for user with username 使用者帳號.

使用 rails

gitlab-rails 改名為 rails
rails console -e production = rails console
enter image description here

docker exec -it synology_gitlab bash
/home/git/gitlab/bin/rails console
--------------------------------------------------------------------------------
 Ruby:         ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux-gnu]
 GitLab:       13.12.2 (d98457affdf) FOSS
 GitLab Shell: 13.18.0
 PostgreSQL:   12.3
--------------------------------------------------------------------------------
Loading production environment (Rails 6.0.3.6)
irb(main):001:0> user = User.where(id: 1).first
=> #<User id:1 @root>
irb(main):002:0> user = User.find_by_username 'root'
=> #<User id:1 @root>
irb(main):003:0> user = User.find(1)
=> #<User id:1 @root>
irb(main):004:0> new_password = 'MyNewP@ssw0rd'
irb(main):005:0> user.password = new_password
irb(main):006:0> user.password_confirmation = new_password
irb(main):007:0> user.password_automatically_set = false
irb(main):008:0> user.save!
irb(main):009:0> exit
docker exec -it synology_gitlab bin/rails console -e production

補充:查看所有使用者列表

users = User.all
users.each do |user|
  puts "ID: #{user.id}, Username: #{user.username}, Email: #{user.email}, Admin: #{user.admin?}"
end

補充:查看所有管理者列表

admins = User.where(admin: true)
admins.each do |admin|
  puts "ID: #{admin.id}, Username: #{admin.username}, Email: #{admin.email}, Admin: #{user.admin?}"
end

補充:查詢使用者

# 替換為實際的用戶 ID
user = User.find_by(id: 1)  
if user
	puts "ID: #{user.id}, Username: #{user.username}, Email: #{user.email}, Admin: #{user.admin?}"
else 
	puts "User not found"
end

2024年4月2日 星期二

VMware Workstation 與 Hyper-V 混合環境

VMware Workstation 與 Hyper-V 共存於 Windows 10 Pro x64 上的奇異狀況

VMware Workstation 要與 Hyper-V 共存於 Windows 10 Pro x64 上需要一番設定

但我今天不是要講這個設定,而是講網路的奇怪狀況

我建立了一個 Ubuntu Desktop Guest,採用 Bridge 模式。
然後看到 Ubuntu Desktop 也取得了與 Win 10 Pro 同網段的 IP Address

這台 Ubuntu Desktop 可以連接到網路上任何其他的電腦,唯獨無法連接到 Win 10 Host。

  1. Ubuntu Desktop Guest 與 Win10 Pro Host互 ping 不到
  2. Ubuntu Desktop ufw/iptables 都沒有設定啟用
  3. Win 10 Pro 防火牆的 ping 規則也有啟用

檢查 VMware Virtual Network Editor 的網路設定,看到 VMnet0 Type Bridge Bridged to 我的 Win 10 Pro 實體網卡名稱 Realtek PCIe GbE Family Controller 看起來也沒錯

突然心血來潮,在命令提示字元下,執行 ipconfig /all
檢查 IP 設定,卻發現Win 10 Pro 取得 DHCP 的網卡是 Hyper-V Virtual Ethernet Adapter #4
而 Realtek PCIe GbE Family Controller 的 IP 卻是 169.254.199.175…

然後我在 VMware Virtual Network Editor 調整 Bridged to Hyper-V Virtual Ethernet Adapter #4 之後,Ubuntu Desktop Guest 與 Win10 Pro x64 就可以正常互連了

至於 Hyper-V Virtual Ethernet Adapter #4 虛擬網卡是如何喧賓奪主,搶走 Realtek PCIe GbE Family Controller 實體網卡的 IP,就不得而知了

我發現以下狀況:

Hyper-V Virtual Ethernet Adapter #4 的 MAC Address ,居然跟 Realtek PCIe GbE Family Controller 的 MAC Address 一模一樣!難怪 DHCP Server的 IP 會被虛擬網卡搶走。

在 Hyper-V 管理員 的 "虛擬交換器管理員",當我把虛擬交換器 Brideg 的外部網路取消掉,改為內部網路之後,Hyper-V Virtual Ethernet Adapter #4 就消失了,然後我的 Realtek PCIe GbE Family Controller 實體網卡就可以正常取得 IP了。
但是這樣的缺點,就是區域網路的電腦,無法連線到我電腦上的 Hyper-V 虛擬機

如果我點選外部網路,並選取 Realtek PCIe GbE Family Controller,Hyper-V 就把我整台電腦的區域網路連線給斷了!除非我勾選 "允許管理作業系統共用此網路介面卡(M)" !

遇到這麼流氓的 Hyper-V,只好把它卸除了,雖然不能用沙箱,也不能用 WSL,也不能用 Docker Desktop....

rsync

rsync 使用簡介

功能簡介:

Linux中的rsync(remote sync)是一個用於在本地系統之間或本地系統和遠程系統之間同步文件和目錄的強大工具。它可以在局域網中高效地傳輸大量數據,並且具有許多功能,使得文件同步和備份變得非常方便。

特點和用途:

  1. 增量備份:rsync可以將文件和目錄從源同步到目標,僅傳輸已更改或新增的部分,這種增量備份方式大大節省了帶寬和時間。
  2. 遠程同步:rsync支持通過SSH等協議在本地和遠程系統之間同步文件和目錄,這使得在不同主機之間進行文件同步變得非常方便。
  3. 保留文件屬性:rsync可以保留文件的屬性,包括權限、時間戳和所有者等信息。
  4. 多種選項:rsync具有多種選項,可以根據需要進行配置,例如遞歸同步、壓縮傳輸、忽略特定文件等。
  5. 傳輸加密:通過使用SSH等加密協議,rsync可以確保在本地和遠程系統之間的安全傳輸。

參數說明:

-a:表示以遞歸方式同步目錄,保留所有檔案屬性。
-v:表示輸出詳細信息,讓您可以看到正在複製的文件。
-z:表示在傳輸過程中壓縮檔案,以節省頻寬。
-h:表示以人類可讀的格式輸出信息。
-e “ssh”:指定使用SSH加密協議。
–ignore-existing:表示在目標目錄中忽略已經存在的文件,不再複製。
–bwlimit:指定一個限制,以Bytes為單位,指定每秒允許的最大傳輸速率。
–delete:刪除目的端不存在於原始路徑的檔案。
–remove-source-files:在成功搬移檔案後,從原始路徑中刪除這些檔案。

指令範例:

List=`ls -ld /volume1/Class/*[0-9] | awk -F' ' '{print $9}'`
for Path in $List; do rsync -avzh --ignore-existing /path/to/source/directory/* user@linux_b_server:/path/to/destination/directory/; done

2024年3月23日 星期六

Powershell 變數特性

Power Shell 是一個弱型別的 Script Language

不需要宣告,變數存甚麼,就是甚麼型態

$a="123"
$a.GetType()

$a = 456
$a.GetType()

Result:

IsPublic IsSerial Name    BaseType                              
-------- -------- ----    --------                              
True     True     String  System.Object                         
True     True     Int32   System.ValueType

要注意的是,變數初始值設定的方法

$a, $b = 1, 2 ,3

Result:

$a = 1      # 數值
$b = 2, 3   # 是陣列

function abc{
    return 1,"A","C"
}

$a, $b = abc
$a.GetType()
$b.GetType()

Result:

IsPublic IsSerial Name       BaseType                              
-------- -------- ----       --------                              
True     True     Int32      System.ValueType                      
True     True     Object[]   System.Array 

一個變數在沒有使用之前,變數等於 $null

Clear-Host
Remove-Variable * -ErrorAction SilentlyContinue

$var -eq $null
$var = 3
$var -eq $null
Clear-Variable var
$var -eq $null

Result:

True
False
True

Powershell 變數型態_String

Powershell 的字串,可以使用對稱的 雙引號,或是單引號

* 如果字串本身包含大括號 { 或 },就要改成 {{ 或 }}
* 如果字串本身有雙引號,就要使用 Double 雙引號 ""
* 如果字串本身有單引號,就要使用 Double 單引號 ''
* 經過格式化字串之後,得到的資料型態為字串
* 如果字串本身有 $,請使用 Double $ 或是跳脫字元 `
* 如果字串本身有 `,請使用 Double `
* 如果字串中要輸出跳行,請使用 `r`n
* 如果字串中要輸出TAB,請使用 `t

例如:

"他的外號叫做""豬頭"""

Result:

他的外號叫做"豬頭"

格式化字串

格式化字串的方法

第一種方式,字串中夾變數

$age = 52
"我的年齡是 $age 歲"

Result:

我的年齡是 52 歲

第二種方式

"格式字串" -f 參數

第三種方法

[string]::format("格式字串", 參數)

數值格式化字串

代號 說明
#
nm m 表示小數位數,不足會補零對齊
dm m 表示數值位數,不足的位數會補零

"{0:n2}" -f 123.5
"{0:n2}" -f 3.14

Result:

123.50
3.14

"{0:d2}" -f 123
"{0:d2}" -f 1

Result:

123
01

"{0:0##,###.#0}" -f 12345.5
"{0:0##,###.#0}" -f 123456.7
"{0:0##,###.#0}" -f 1234567.579

Result:

  • 整數位數,不足會補零
  • 小數位數,不足會補零
  • 小數位數超過的,會四捨五入
012,345.50
123,456.70
1,234,567.58

日期型態資料的格式化字串

代號 說明
y yyyy年MM月
yy yy 兩位數西元年
yyyy yyyy 四位數西元年
M MM月dd日
MM MM 兩位數月份,不足兩位數,前面會補0
d yyyy/MM/dd
dd dd 兩位數日期,不足兩位數,前面會補0
hh 兩位數12小時制(不足兩位數,前面會補0)不會顯示 AM/PM 或上午/下午
HH 兩位數24小時制(不足兩位數,前面會補0)
mm 兩位數分鐘(不足兩位數,前面會補0)
s yyyy-MM-ddTHH:mm:ss
ss 兩位數秒(不足兩位數,前面會補0)
f yyyy年M月dd日 上午/下午 hh:mm
ff 兩位數毫秒
fff 三位數毫秒
ddd 周一、周二、周三…
dddd 星期一、星期二、星期三…

小百岳

小百岳列表

編號 山名 縣市別 鄉鎮市區別 別名 難度 座標 標高(m) 備註
1 大屯山 台北市、新北市 北投區、淡水區 1.3 1092
2 七星山 台北市 北投區 1.4 1120
3 大武崙山 基隆市 安樂區 砲台山 0.6 231 近中山區界
4 槓子寮山 基隆市 中正區 槓子寮砲台 0.1 25.143730986822487, 121.7819003870428 163
5 觀音山 新北市 八里區 硬漢嶺 1.5 25.135933897405756, 121.42666847085579 616 2023/11/19已達成
6 基隆山 新北市 瑞芳區 大肚美人山 0.9 588
7 紅淡山 基隆市 仁愛區 0.8 210
8 大崙頭山 台北市 士林區、內湖區 0.3 478
9 劍潭山 台北市 士林區 0.3 153 2024/01/27已達成
10 五分山 新北市 瑞芳區、平溪區 0.1 757
11 姜子寮山 基隆市 七堵區 三角架山 0.9 729
12 汐止大尖山 新北市 汐止區 0.5 460
13 南港山 台北市 信義區、南港區 0.8 375 2024/01/20已達成
14 土庫岳 新北市 深坑區 大坪山 0.2 389 近南港區界
15 大棟山 新北市、桃園市 樹林區、龜山區 1.2(0) 405
16 南勢角山 新北市 中和區、新店區 風爐塞山 2.1 302
17 二格山 台北市、新北市 文山區、石碇區 石尖山 2.4 678[1]
18 天上山 新北市 土城區 皇帝山 0.4 429
19 福德坑山 新北市 三峽區 鳶山 0.3 321 並非標高300公尺之鳶山
20 獅仔頭山 新北市 新店區、三峽區 1.7 858
21 金面山 桃園市 大溪區 鳥嘴尖 1.4 667
22 東眼山 新北市、桃園市 三峽區、復興區 0.7 1212 2024/02/03已達成
23 溪洲山 桃園市 大溪區 1.8 577
24 石門山 桃園市 龍潭區 小竹坑山 1.6 551
25 石牛山 桃園市、新竹縣 復興區、關西鎮 1.5 671
26 十八尖山 新竹市 東區 0.1 130
27 飛鳳山 新竹縣 芎林鄉 中坑山 1.7 462 非423m的飛鳳山,而是二等三角點的中坑山
28 李崠山 桃園市、新竹縣 復興區、尖石鄉 李棟山 1.2 1914
29 獅頭山 苗栗縣 三灣鄉、南庄鄉 0.3 492
30 五指山 新竹縣 竹東鎮、北埔鄉、五峰鄉 1.8 1062
31 鵝公髻山 新竹縣、苗栗縣 五峰鄉、南庄鄉 1.8 1579
32 向天湖山 苗栗縣 南庄鄉 1.9 1225
33 仙山 苗栗縣 獅潭鄉 紅毛館山 0.5 967
34 加里山 苗栗縣 南庄鄉、泰安鄉 加里仙山 2.4 2210 台灣富士山,注意可能有高山症
35 火炎山 苗栗縣 苑裡鎮、三義鄉 1.7 596
36 關刀山 苗栗縣 三義鄉、大湖鄉 1 889
37 馬那邦山 苗栗縣 大湖鄉、泰安鄉 馬拉邦山 2 1407 近卓蘭鎮界
38 鐵砧山 台中市 外埔區 0.2 236 跨大甲區境
39 稍來山 台中市 和平區 0.7 2307 注意可能有高山症
40 聚興山 台中市 潭子區 0.8 500
41 頭嵙山 台中市 北屯區、新社區 0.7 859
42 南觀音山 台中市 北屯區 0.3 318
43 三汀山 台中市 太平區 1.5 480
44 暗影山 台中市 太平區 酒桶山 1 997
45 大橫屏山 台中市、南投縣 太平區、國姓鄉 2.1 1205
46 阿罩霧山 台中市 霧峰區 0.1 249
47 九份二山 南投縣 中寮鄉、國姓鄉 0.6 1174
48 橫山 南投縣 南投市、名間鄉 1.5(0.2) 444 近彰化縣社頭鄉界
49 貓囒山 南投縣 魚池鄉 0.8 1016
50 集集大山 南投縣 集集鎮、中寮鄉 0(2.8) 1392 近水里鄉界
51 松柏坑山 彰化縣、南投縣 二水鄉、名間鄉 松柏嶺 1(0) 430
52 後尖山 南投縣 魚池鄉、水里鄉 1 1008
53 鳳凰山 南投縣 鹿谷鄉 2.1 1696
54 金柑樹山 南投縣 竹山鎮、信義鄉 2.8 2091
55 石壁山 雲林縣、嘉義縣 古坑鄉、阿里山鄉 1.5 1751 近竹山鎮界
56 雲嘉大尖山 雲林縣、嘉義縣 古坑鄉、梅山鄉 1.5 1299
57 梨子腳山 嘉義縣 梅山鄉 掘尺嶺山、 祝壽山 0.2 1176
58 獨立山 嘉義縣 竹崎鄉 1 840
59 大塔山 嘉義縣、南投縣 阿里山鄉、信義鄉 1.7 2663 注意可能有高山症
60 大凍山 嘉義縣 梅山鄉、阿里山鄉 畚箕山、糞箕山 0.8 1967 近竹崎鄉界
61 大湖尖山 嘉義縣 竹崎鄉、番路鄉 0.9-2 1313
62 紅毛埤山 嘉義市 東區 0.5(0.1) 150
63 大凍山 臺南市、嘉義縣 白河區、大埔鄉 凍頭山 1.5 1241
64 崁頭山 臺南市 東山區 0.5 844
65 三腳南山 嘉義縣、臺南市 大埔鄉、南化區 2.1 1186
66 西阿里關山 臺南市、高雄市 南化區、甲仙區 小林山 0.5 973
67 竹子尖山 臺南市 楠西區、南化區 1.1 1090
68 東藤枝山 高雄市 桃源區 藤枝山 0.7 1565 新入選
69 白雲山 高雄市 甲仙區 廓亭山 1.1 1044
70 烏山嶺 臺南市、高雄市 南化區、杉林區 刣牛湖山、烏山步道 2.2 730
71 鳴海山 高雄市 茂林區 2.9 1411
72 旗尾山 高雄市 旗山區 0.3 318
73 尾寮山 屏東縣、高雄市 茂林區、三地門鄉 2.5 1427
74 大崗山 高雄市 岡山區、阿蓮區、田寮區 0.6 312
75 觀音山 高雄市 大社區、仁武區 2 169
76 笠頂山 屏東縣 瑪家鄉 1.4 659
77 壽山 高雄市 鼓山區 柴山 0.5 356
78 棚集山 屏東縣 來義鄉 1.8 899
79 女仍山 屏東縣 獅子鄉、牡丹鄉 2.2 804
80 里龍山 屏東縣 獅子鄉、牡丹鄉 里瀧山 1.4 1062
81 大山母山 屏東縣 滿州鄉 萬里得山 #N/A 325 新入選
82 灣坑頭山 宜蘭縣 頭城鎮 2.5 616 2024/02/10已達成
83 三角崙山 新北市 坪林區 2.2 1029
84 鵲子山 宜蘭縣 礁溪鄉 鴻子山 0.3 679 礁溪富士山
85 三星山 宜蘭縣 大同鄉 0.9 2352
86 卡拉寶山 花蓮縣 秀林鄉 祖輪山 #N/A 2397 注意可能有高山症
87 立霧山 花蓮縣 秀林鄉 2.5 1274
88 初音山 花蓮縣 吉安鄉、秀林鄉 0.2(0.3) 906
89 鯉魚山 花蓮縣 壽豐鄉 1 601
90 月眉山 花蓮縣 壽豐鄉 0.6 614
91 八里灣山 花蓮縣 豐濱鄉、瑞穗鄉 貓公富士山 2.8 924
92 萬人山 花蓮縣 富里鄉 0.1 886
93 都蘭山 台東縣 東河鄉、延平鄉 都巒山 1.9 1190 台東富士山
94 太麻里山 台東縣 太麻里鄉 金針山 0 1340
95 加奈美山 台東縣 大武鄉 1.6 780
96 巴塱衛山 台東縣 大武鄉 0 324
97 紅頭山 台東縣 蘭嶼鄉 1.7 552
98 雲台山 連江縣 南竿鄉 0 248
99 太武山 金門縣 金湖鎮 0.6 253 已達成
100 蛇頭山 澎湖縣 馬公市 0 20

2024年3月13日 星期三

Powershell 變數型態_Array

Array

  • 同一陣列內,可以混合儲存各種形態資料
  • 陣列起始註標為 0

陣列的表示法

$a1 = 1..3
$a2 = 1,2,3
$a3 = @(1,2,3)
$a4 = (1..3), "ABC", (7..9), @{'name'="tom"; "age"=51}

Result

$a4[0] = 1, 2, 3
$a4[1] = "ABC"
$a4[2] = 7, 8, 9

宣告空陣列

$a5 = @()
$a5.Count -eq 0    # True

只有一個變數值,要設定為陣列

$a6 = , "Hello"
$a7 = @("Hello")
# 輸出 $a6 變數註標值為0的元素
$a6[0]
# 輸出 $a7 變數註標值為0的元素
$a7[0]
$a6.GetType()
$a7.GetType()

Result:

Hello
Hello

IsPublic IsSerial Name     BaseType                  
-------- -------- ----     --------                  
True     True     Object[] System.Array              
True     True     Object[] System.Array

反向取得陣列值

$array = "Tom", "Kate", "Dylan"
$array[-1]   # 陣列最後一個值
$array[-2]   # 陣列倒數第二個值

Result:

Dylan
Kate

計算陣列中符合條件值的數量(篩選等於 100,再計算 Count)

$a8 = @(100, 59, 95, 60, 100, 88, 76)
($a8 -eq 100).Count # 統計滿分人數

Array 元素的增加

雖然 Array 有 Add Method,但是當你使用 Add() 時,會出現"集合屬於固定大小"的錯誤
所以當你要在 Array 增加元素時,請使用數學運算 +

$a=@()
$a += 1
$a.GetType()
$a.Add(5)
$a += 5
$a

Result:

IsPublic IsSerial Name                                     BaseType                  
-------- -------- ----                                     --------                  
True     True     Object[]                                 System.Array              
以 "1" 引數呼叫 "Add" 時發生例外狀況: "集合屬於固定大小。"
位於 線路:4 字元:1
+ $a.Add(5)
+ ~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : NotSupportedException
 
1
5

雖然空一格,但不占空間

$a = @(1,2,3, ,5)
$a.count
$a

Result

4
1
2
3
5

Array 元素的減少

$a = @(1,2,3,4,5,6,7,8,9)
# 用註標來選擇
$a = $a[1,3,5]
$a

Result:

2
4
6

移除陣列中的空字串

# 宣告一個陣列
$a = @(1, 2, "", 4)
# 以下三種方法都可以移除空字串
$a = $a.Where( { $_ -ne ""} )
$a = $a | Where-Object { $_ -ne "" }
$a = $a -ne ""

Arrary 與 ArrayList 型態互換

$a = @()
$a.GetType()
# 將 [System.Array] 轉換成 [System.Collections.ArrayList]
$a = [System.Collections.ArrayList]$a
$a.GetType()
# [System.Collections.ArrayList] 轉換成 [System.Array]
$a = [System.Array]$a

Result:

IsPublic IsSerial Name       BaseType                  
-------- -------- ----       --------                  
True     True     Object[]   System.Array              
True     True     ArrayList  System.Object             

https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_arrays?view=powershell-7.3