Linux 相關

Posted by Adam on August 24, 2022

常用資料夾

  1. /bin:存放系統的二進位檔案,包括一些基本的系統命令。

  2. /sbin:包含系統管理指令,例如重新啟動或關機系統等。

  3. /usr - 存放使用者的程式、庫檔案等。

  4. /usr/bin:包含用戶安裝的程式指令。

  5. /usr/sbin:包含用戶安裝的系統管理指令。

  6. /usr/local/bin:包含本地系統或使用者安裝的指令。

  7. /etc:存放系統的設定檔案和配置檔案。

  8. /opt:包含第三方應用程式的安裝目錄,有時也可能會有指令被安裝至此目錄。

  9. /lib:包含程式庫檔案,一些指令可能會需要存取這些庫檔案來正常執行。

  10. /usr/lib:跟/lib類似,但是存放的是用戶安裝的程式庫檔案。

  11. /usr/local/lib:本地系統或使用者安裝的程式庫檔案。

  12. /home - 存放使用者的家目錄,每個使用者有自己的家目錄。

  13. /var - 存放系統的變數資料,例如日誌檔案、暫存檔案等。

  14. /tmp - 存放臨時檔案和暫存檔案。

  15. /root - 超級使用者(root)的家目錄。

  16. /dev - 存放系統裝置的特殊檔案,如硬碟、網路介面等。

  17. /proc - 包含系統核心的資料,如處理器資訊、記憶體使用等。

curl

curl -X GET http://localhost:8080/

curl -X POST --data "email=test@example.com&press=%20OK%20"  http://www.example.com/form.php

curl -X DELETE http://localhost:8080/user/100

# with header
curl -v -i -H "Content-Type: application/json" http://www.example.com/users

# 配合 body
curl http://localhost:47267/sdcv/query.html -d '{"q":"apple"}'

# GET 配合 urlencode
curl -G \
	--data-urlencode "p1=value 1" \
	--data-urlencode "p2=value 2" \
	http://example.com
	# http://example.com?p1=value%201&p2=value%202

# POST 附帶檔案
curl -H "Content-Type: application/json" \
	--data @body.json http://localhost:8080/ui/webapp/conf

# POST 附帶檔案(Path)
curl -i -X POST host:port/post-file \
	-H "Content-Type: text/plain" \
	--data-binary "@path/to/file"

curl -s -o /dev/null -w "%{http_code}" example.com:1300
# 在上面的示例中,我們使用 curl 命令連接到 example.com 的 1300 端口
# 並使用 -s 選項使 curl 靜默執行
# -o /dev/null 選項將輸出重定向到 /dev/null(即丟棄輸出)
# -w "%{http_code}" 選項指定 curl 的輸出格式為 HTTP 狀態碼。

# 上傳檔案並顯示進度
curl --location --request POST 'https://example.com/upload' \
--form 'file=@"/home/adam/Downloads/archive.zip"' \
-o /dev/null \
--progress-bar

在 curl 命令中,"--location"(或"-L")是一個可選參數,其用途是讓 curl 自動跟隨 HTTP 重定向。這在從一個 URL 下載文件時常常很有用。

當用戶請求一個 URL 時,有時服務器會向用戶返回一個 HTTP 重定向響應,指示用戶重新將請求發送到新的 URL 上。如果 curl 沒有設置 "--location",它將僅獲取重定向頁面的內容,而不會自動重新導向到新的 URL。這可能導致只下載了重定向頁面而非期望的實際文件。

使用 "--location" 參數後,curl 將根據服務器的指示自動重新導向到新的 URL,並下載該 URL 所指向的內容。這使得用戶能夠輕鬆地下載原始請求 URL 的數據。

以下是一個例子,展示了如何使用 --location 參數:

curl --location https://example.com

上述命令將使用 curl 自動跟隨重定向,並下載該 URL 所指向的內容。

nc

nc 是一個用於網絡通信的指令行工具,其名稱來源於 "netcat"。它可以通過TCP或者UDP協議進行數據交換,可以用來進行端口掃描、端口監聽、數據傳輸等操作。

以下是一些 nc 指令的常見用法:

  1. 執行端口掃描:
nc -zv example.com 1-100

這個命令將掃描 example.com 主機的1至100號端口, -z 表示只檢查端口的狀態,不進行數據傳輸, -v 表示顯示詳細的輸出信息。

  1. 監聽指定端口:
nc -lvp 1234

這個命令將監聽本地的1234號端口, -l 表示啟動監聽模式, -v 表示顯示詳細的輸出信息, -p 指定要監聽的端口。

  1. 使用 nc 傳送文件:
nc -w 3 example.com 1234 < file.txt

這個命令將本地的 file.txt 文件傳送到遠程主機 example.com 的1234號端口, -w 指定超時時間。

這些只是 nc 命令的一些常見用法,通過結合不同的參數以及管道,nc 可以實現更多功能。請參考 nc 的 man 頁面以獲取更多信息。

strace

strace 是一個在 Linux 上偵錯、跟蹤系統調用的工具。它可以追蹤系統調用和信號,並顯示系統調用所花費的時間、傳遞的參數和返回的值,這對於排除一些程序執行時的錯誤非常有用。

strace -o output.txt curl https://www.example.com

下面是使用strace命令來查詢某個指令使用哪一個DNS來連線的步驟:

  1. 使用以下命令來執行strace並追蹤指定命令的系統調用:
sudo strace -e trace=network -f -s 10000 command
  1. 在上面的命令中,將“command”替換為要查詢的命令,例如“ping example.com”。

  2. 執行上面的命令後,strace會列印出該命令使用的所有系統調用,根據輸出可以確定該命令使用的DNS伺服器。

注意:請確保在使用strace時小心,因為這樣可能會暴露系統中的敏感信息。

Linux 中使用 curl 代替 telnet

curl -vv telnet://192.168.1.101:8080

zcat

zcat 是一個用於顯示壓縮的 gzip 格式文件內容的指令。它實際上是 gzcat 的一個符號連結,這兩者之間的差異主要是名稱。在某些系統上,zcatgzcat 可能是同一個程式的不同名稱,而在其他系統上可能是不同的實現。

以下是 zcat 的簡單使用說明:

zcat filename.gz

這個命令將解壓縮 filename.gz 並將其內容顯示在終端上,而不需要事先解壓縮文件。

如果 zcatgzcat 都不存在,你可以使用以下命令達到相同的效果:

gzip -dc filename.gz

這裡的選項 -d 表示解壓縮,而 -c 表示將解壓縮的內容輸出到標準輸出。上述命令與 zcat filename.gz 效果相同。

請注意,zcatgzcat 只能用於 gzip 格式的壓縮檔(擴展名為 .gz)。如果你有其他壓縮格式的檔案,如 .xz.zip,則需要使用相應的工具(如 xzcatunzip)來解壓縮和查看內容。

wc

wc 是一個用來計算文件中字數、行數和字符數的指令。

舉例來說,如果我們想要知道一個檔案中有多少行、多少字和多少字符,只需要在終端機中輸入以下指令:

wc test.txt

這樣就能得到該檔案中的行數、字數和字符數的統計結果。

假設我們有一個名為example.txt的文件,其中包含以下內容:

這是第一行
這是第二行
這是第三行

要計算這個文件的行數,可以使用以下命令:

wc -l example.txt

這樣就會列出該文件的行數,結果應該是3行。

如果想要同時計算字數和字符數,可以使用以下命令:

wc -l -w -m example.txt

這樣就會列出該文件的行數、字數和字符數。

於 Bash 中使用 Map

#!/bin/bash
# declare 為 bash 的指令,需要將檔案修改成可執行檔直接執行
declare -A myMap
myMap["a"]="01"
myMap["b"]="02"
for key in ${!myMap[@]}; do
	echo "key:"$key;
	echo "values:"${myMap[$key]};
done
# key:b
# values:02
# key:a
# values:01

sort

#!/bin/bash

rm /tmp/some.txt
echo "TrueOS,$(( $RANDOM % 10 + 1 )),$(( $RANDOM % 100 ))" >> /tmp/some.txt
echo "Mint,$(( $RANDOM % 10 + 1 )),$(( $RANDOM % 100 ))" >> /tmp/some.txt
echo "Debian,$(( $RANDOM % 10 + 1 )),$(( $RANDOM % 100 ))" >> /tmp/some.txt
echo "Solus,$(( $RANDOM % 10 + 1 )),$(( $RANDOM % 100 ))" >> /tmp/some.txt
echo "Ubuntu,$(( $RANDOM % 10 + 1 )),$(( $RANDOM % 100 ))" >> /tmp/some.txt
echo "Antergos,$(( $RANDOM % 10 + 1 )),$(( $RANDOM % 100 ))" >> /tmp/some.txt
echo "elementary,$(( $RANDOM % 10 + 1 )),$(( $RANDOM % 100 ))" >> /tmp/some.txt
echo "Manjaro,$(( $RANDOM % 10 + 1 )),$(( $RANDOM % 100 ))" >> /tmp/some.txt
echo "openSUSE,$(( $RANDOM % 10 + 1 )),$(( $RANDOM % 100 ))" >> /tmp/some.txt
echo "Fedora,$(( $RANDOM % 10 + 1 )),$(( $RANDOM % 100 ))" >> /tmp/some.txt

sort /tmp/some.txt
echo "--------------------------------------------------"
cat /tmp/some.txt | sort
echo "反向排序"
sort -r /tmp/some.txt
echo "根據各行特定欄位排序"
echo "-t, 之後串接「分隔符號」"
echo "-ka,b a表示起始位置,b表示結束位置"
sort -t, -k2,2 -n /tmp/some.txt
echo "--------------------------------------------------"
sort -t, -k2 /tmp/some.txt

uniq 移除重覆內容

serial.txt 檔案內容

10 => wAwbwCM8x7
11 => wAwbwCM8x7
12 => iwFSRivUPlVI
13 => wAwbwCM8x7
14 => iwFSRivUPlVI
14 => iwFSRivUPlVI
uniq -s 2 serial.txt # 略過前兩個字元
10 => wAwbwCM8x7
12 => iwFSRivUPlVI
13 => wAwbwCM8x7
14 => iwFSRivUPlVI

serial.txt 檔案內容

wAwbwCM8x7
wAwbwCM8x7
iwFSRivUPlVI
wAwbwCM8x7
iwFSRivUPlVI
iwFSRivUPlVI
uniq serial.txt #刪除重覆行
wAwbwCM8x7
iwFSRivUPlVI
wAwbwCM8x7
iwFSRivUPlVI

sort serial.txt | uniq #排序後刪除重覆行
iwFSRivUPlVI
wAwbwCM8x7

How to sort lines of text files in Linux?

sort text.txt > newtext.txt

tcpdump

# 檢查 host 192.168.0.1 封包
tcpdump -i eth0 'host 192.168.0.1' -X

# 檢查 host 192.168.0.1 port 22 的 tcp 封包
tcpdump -i eth0 'tcp port 22 and host 192.168.0.1'

# 檢查封包,合併使用
tcpdump -i eth0 'tcp and (not port 22) and (net 192.168.0.0/24)'

watch

watch -n 5 netstat # 每 5 秒執行一次 netstat
watch -n 1 sensors # 每 1 秒執行一次 sensors
watch -n 1 "last | grep still"

watch -d ls -l # 標示輸出差異之處

watch -c ls --color # 解析 ANSI 顏色與樣式
watch -c -d -n 1 netstat -ntu

ps

# https://linux.vbird.org/linux_basic/centos7/0440processcontrol.php#process_1
# 觀察系統所有的程序資料
ps aux
# 查閱自己 bash 程序
ps -l
# 觀察系統所有的程序資料,連同部分程序樹狀態
ps axjf

# How to find zombie process?
# https://askubuntu.com/questions/111422/how-to-find-zombie-process
ps aux | grep 'Z'

pstree

# 顯示 PID 並排序
pstree -np
# 顯示特定 PID 行程
pstree -p 2061

ssh

# Send Remote Commands Via SSH
# https://malcontentcomics.com/systemsboy/2006/07/send-remote-commands-via-ssh.html
ssh systemsboy@rhost.systemsboy.edu "cd /tmp/${name}/ ; ls -l; ps -aux; whoami"
# Note the -t flag. That tells ssh that you'll be interacting with remote shell.
ssh -t systemsboy@rhost.systemsboy.edu 'top'

rsync

rsync -avzh /mypath/myfile.gz pi@192.168.1.12:/mybackup/
#   -v:verbose 模式,輸出比較詳細的訊息。
#   -r:遞迴(recursive)備份所有子目錄下的目錄與檔案。
#   -a:封裝備份模式,相當於 -rlptgoD,遞迴備份所有子目錄下的目錄與檔案,保留連結檔、檔案的擁有者、群組、權限以及時間戳記。
#   -z:啟用壓縮。
#   -h:將數字以比較容易閱讀的格式輸出。
rsync -avzh --bwlimit=100K pi@192.168.1.12:/mypath/myfile.gz /mybackup/
#   --bwlimit 參數來指定資料傳輸的速度上限
rsync --bwlimit=1M source/ destination/
rsync -avzh --progress pi@192.168.1.12:/mypath/myfile.gz /mybackup/
#   --progress 備份每個檔案的過程就會顯示傳輸的進度、傳輸速度與剩餘時間等資訊
rsync -avh --exclude '*.txt' myfolder/ backup/
rsync -avh --exclude '*.txt' --exclude '*.py' myfolder/ backup/
rsync -avh --include '*.c' --include '*/' --exclude '*' myfolder/ backup/
# 同步刪除檔案
rsync -avh --delete myfolder/ backup/

# test1/tmp.txt
# test2/
rsync -avh test1/tmp.txt test2 # test2/tmp.txt
rsync -avh test1/tmp.txt test2/temp.txt # test2/temp.txt
rsync -avh test1 test2 # test2/test1/tmp.txt
rsync -avh test1/ test2 # test2/tmp.txt
rsync -avh test1/ test2/ # test2/tmp.txt
rsync -avh test1 test2/ # test2/test1/tmp.txt

ffmpeg

使用 ffmpeg 來修復損壞的 MP4 文件可以通過重新封裝(repackaging)的方式來實現。這裡提供一個基本的命令示例:

ffmpeg -i damaged.mp4 -c copy fixed.mp4

這個命令的含義是:

  • -i damaged.mp4: 指定輸入文件,這是損壞的 MP4 文件的路徑。
  • -c copy: 表示使用複製(copy)方式重新封裝。這樣會將文件中的音頻和視頻流直接複製到新的文件中,而不進行重新編碼。
  • fixed.mp4: 指定輸出文件,這是修復後的 MP4 文件的路徑。

這樣的命令通常適用於那些損壞主要是由於文件頭部信息損壞而無法正確解析的情況。如果文件中的實際數據流(音頻和視頻)沒有受損,這種方法通常是有效的。

請注意,如果 MP4 文件的實際數據流也受到損壞,那麼這種方法可能無法修復問題。在這種情況下,可能需要其他進一步的操作或者專業的工具進行修復。

top

nmap

nmap 192.168.0.*
nmap -v www.hinet.net # for detail
nmap -A scanme.nmap.org # for complete detail
nmap -O scanme.nmap.org # for OS
nmap -sA scanme.nmap.org # 透過 TCP ACK 掃描,偵測主機是否有啟用防火牆
nmap -PN scanme.nmap.org # 掃描在防火牆保護下的主機
nmap -sP 140.115.35.0/24 # 掃描整個網路,偵測所有有開機的主機

ISO to USB

https://blog.gtwang.org/linux/dd-command-examples/

lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda      8:0    0 111.8G  0 disk
└─sda1   8:1    0 111.8G  0 part /
sdb      8:16   0 931.5G  0 disk
├─sdb1   8:17   0   250G  0 part
└─sdb2   8:18   0 681.5G  0 part /home
sdc      8:32   0 149.1G  0 disk
├─sdc1   8:33   0   500M  0 part
└─sdc2   8:34   0 148.6G  0 part
sudo dd if=ubuntu-16.10-desktop-amd64.iso of=/dev/sdc bs=1M

if=FILE:指定輸入檔案名稱(input file)為 FILE

of=FILE:指定輸出檔案名稱(output file)為 FILE

bs=BYTES:指定 block size,一次讀取與寫入 BYTES 位元組的資料,此選項會覆蓋 ibs 與 obs 的設定

Fix terminal after displaying a binary file

reset

bash: fork: retry: Resource temporarily unavailable

ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 31008
max locked memory       (kbytes, -l) 65536
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 31008
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

cat /etc/security/limits.d/90-nproc.conf
# Default limit for number of user's processes to prevent
# accidental fork bombs.
# See rhbz #432903 for reasoning.
 
*          soft    nproc    4096

解壓縮zip檔案,遇到檔案名稱是big5編碼,產生亂碼時,如何解決?

unzip -O big5 Open_Data.zip

###Linux 如何查看 主機板型號

sudo lshw -short
sudo dmidecode -t 2

ss

# -t: TCP
# -u: UDP
# -4: IPv4
# -6: IPv6
# -p: display process info
# -n: list port or ip
# -l: list listener port
ss -tulpn4 | grep LISTEN

怎麼檢查 debian 版本

cat /etc/debian_version
uname -a

怎麼檢查 Ubuntu 版本

cat /etc/os-release

怎麼安裝 deb 檔

sudo dpkg -i package.deb
# 如果出現依賴問題可用以下命令解決
sudo apt --fix-broken install

定時關機

crontab -e

30 23 * * * /sbin/shutdown -h now

安装特定版本的 GCC

#查找可用的版本
apt-cache policy gcc
sudo apt-get install gcc=7.5.0
gcc --version

對目前資料下的所有檔案檔名 Regex 操作

# 對目前資料下的所有檔案檔名中有 [ ] 或空白的字元皆換成底線(_)
for file in ./*; do mv "$file" "${file//[\[ \]]/_}"; done
# 對目前資料下的所有檔案檔名中有雙底線(__)的字元皆換成底線(_)
for file in ./*; do mv "$file" "${file//__/_}"; done

# 將底線中間的數字作為流水號 檢測結果
for file in ./*; do echo "$file" | sed 's/.*_\([0-9]\+\)_.*/File\1/'; done
# 將底線中間的數字作為流水號
for file in ./*; do
    new_name=$(echo "$file" | sed 's/.*_\([0-9]\+\)_.*/File\1/')
    mv "$file" "$new_name"
done

顯示檔案的完整路徑

realpath filename
readlink -f filename # 顯示符號連結(symbolic link)的目標檔案的絕對路徑。

將大檔案每1000行分割出一個檔案

split -l 1000 filename prefix
# filename是要分割的文件的名称
# prefix是生成的分割文件的前缀
split -l 1000 -d filename prefix
# -d 或 --numeric-suffixes,用於生成數字流水號作為文件名的後綴
split -b 1M input.txt output
# -b <大小>:按指定的大小(以位元組、K、M、G 等表示)分割檔案

# cat 命令用於合併多個檔案。你可以使用以下命令將分割後的檔案合併為單一檔案
cat output* > merged.txt

網路卡變更 MAC Address

在 Linux 中,您可以使用 ifconfigip 命令來更改網卡的 MAC 地址。以下是一個使用 ip 命令的示例:

注意:在更改 MAC 地址之前,請確保您已經關閉該網卡。

  1. 首先,使用以下命令查看網卡的名稱:

    ip link
    

    輸出類似於:

    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    2: enp0s25: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
        link/ether 12:34:56:78:90:ab brd ff:ff:ff:ff:ff:ff
    

    在此示例中,enp0s25 是網卡的名稱。

  2. 關閉網卡:

    sudo ip link set dev enp0s25 down
    

    這將關閉 enp0s25 網卡。

  3. 更改 MAC 地址:

    sudo ip link set dev enp0s25 address new_mac_address
    

    請將 new_mac_address 替換為您想要設置的新 MAC 地址,例如 12:34:56:78:90:cd

  4. 啟用網卡:

    sudo ip link set dev enp0s25 up
    

    這將啟用 enp0s25 網卡,並應用新的 MAC 地址。

  5. 驗證更改:

    ip link show enp0s25
    

    您應該看到 enp0s25 網卡的新 MAC 地址。

請注意,這種更改是臨時的,並且在下次重新啟動系統之後將恢復為原始的 MAC 地址。如果您想要使更改永久,您可以在網卡的配置文件中設置新的 MAC 地址。

ip route

在 Linux 中,您可以使用 ip route 命令來查詢、新增、刪除和修改路由表條目。以下是一些基本的範例:

查詢路由條目

要查詢路由條目,您可以使用 ip route showip route list 命令。以下是一個範例:

ip route show

這個命令將顯示完整的路由表條目列表。

新增路由條目

要新增一個路由條目,您可以使用 ip route add 命令。以下是一個範例:

sudo ip route add 192.168.2.0/24 via 192.168.1.1

這個命令將向目的地網路 192.168.2.0/24 添加一條路由,經由網關 192.168.1.1

刪除路由條目

要刪除一個路由條目,您可以使用 ip route del 命令。以下是一個範例:

sudo ip route del 192.168.2.0/24

這個命令將刪除目的地網路 192.168.2.0/24 的路由。

修改路由條目

要修改一個路由條目,您可以先刪除該條目,然後再新增修改後的條目。例如,假設您要修改先前的例子中的路由:

sudo ip route del 192.168.2.0/24
sudo ip route add 192.168.2.0/24 via 192.168.1.2

這個例子中,我們先刪除了先前的路由,然後新增了一個修改後的路由。

請注意,這些命令可能需要使用 sudo 或具有相應權限的使用者執行,具體取決於系統設置。

刪除 jobs 中的第一項

jobs
kill %1

sdcv

安裝

# Debian, Ubuntu.
$ sudo aptitude install sdcv

# CentOS, RHEL, Fedora (need EPEL repo)。
$ sudo yum install sdcv

下載字典檔

# 朗道英漢字典
$ wget http://abloz.com/huzheng/stardict-dic/zh_TW/stardict-langdao-ec-big5-2.4.2.tar.bz2

# 朗道漢英字典
$ wget http://abloz.com/huzheng/stardict-dic/zh_TW/stardict-langdao-ce-big5-2.4.2.tar.bz2

安裝字典檔

# 於家目錄底下建立字典檔目錄。
$ mkdir -p $HOME/.stardict/dic

# 將字典檔解壓縮至 $HOME/.stardict/dic。
$ tar jxvf /dev/shm/stardict-langdao-ce-big5-2.4.2.tar.bz2 -C $HOME/.stardict/dic

$ tar jxvf /dev/shm/stardict-langdao-ec-big5-2.4.2.tar.bz2 -C $HOME/.stardict/dic

md5sum

要在Linux上計算文件的MD5,您可以使用以下指令:

md5sum 文件名

這樣就會計算並顯示文件的MD5值。您還可以將這個數據寫入文件,例如:

md5sum 文件名 > md5.txt

這樣就會將MD5值寫入md5.txt文件中。

shasum

要在Linux系統上計算文件的SHA1或SHA256,您可以使用以下命令:

計算文件的SHA1散列值:

sha1sum 文件名

計算文件的SHA256散列值:

sha256sum 文件名

只需將「文件名」替換為您要計算散列值的文件名即可。結果將以十六進制表示。

取得資料夾中最新的 jar 檔 並複製到另一個資料夾

要在Linux中取得資料夾中最新的jar檔並複製到另一個資料夾,可以使用以下指令:

cp $(ls -t /path/to/source/directory/*.jar | head -1) /path/to/destination/directory/

這個指令將會依據最後修改時間順序列出資料夾中所有的jar檔案,然後取得列表中的第一個檔案(即最新的jar檔),最後將其複製到目標資料夾中。

請替換/path/to/source/directory//path/to/destination/directory/為實際的資料夾路徑。

Permission denied 可能的原因

如果在 Alpine Linux 上,新使用者嘗試執行一個權限為 777 的自訂執行檔卻仍然出現 Permission denied,可能的原因包括以下幾點:


🔍 可能原因與解法

1️⃣ 掛載點的 noexec 限制

🔹 可能原因:
如果執行檔所在的檔案系統或目錄被掛載時使用了 noexec,則該目錄下的所有執行檔都無法執行,即使它們的權限是 777

🔹 解決方法:

  1. 先確認該檔案所在的掛載點:
    mount | grep /path/to/executable
    
  2. 如果看到 noexec,表示該掛載點禁止執行程式。例如:
    /dev/sda1 on /mnt type ext4 (rw,noexec,relatime)
    
  3. 若要允許執行,可重新掛載:
    mount -o remount,exec /mnt
    
    或編輯 /etc/fstab,找到相關掛載點並移除 noexec,然後重新掛載:
    mount -o remount /mnt
    

2️⃣ 執行檔缺少適當的 Shebang (#!)

🔹 可能原因:
若該檔案是 shell script,但缺少適當的 Shebang(如 #!/bin/sh),則可能無法執行。

🔹 解決方法:

  • 確保第一行有正確的 Shebang,例如:
    #!/bin/sh
    
  • 若無 Shebang,可以手動執行:
    sh /path/to/executable
    

3️⃣ 檔案的 setfacl 限制

🔹 可能原因:
即使檔案權限是 777,但如果 ACL(存取控制列表)限制了某些使用者,則他們仍無法執行該檔案。

🔹 解決方法:

  1. 檢查 ACL 設定:
    getfacl /path/to/executable
    
  2. 如果發現有 user:username:---,則表示該使用者被禁止執行。可以移除 ACL 限制:
    setfacl -x u:username /path/to/executable
    

4️⃣ 檔案系統不支援執行權限

🔹 可能原因:
某些檔案系統(如 vfatexfat)不支援 UNIX 權限,因此即使 chmod 777,仍然無法執行。

🔹 解決方法:

  • 確認檔案系統:
    df -T /path/to/executable
    
  • 若顯示 vfatexfat,則需要將檔案移動到支援執行權限的檔案系統,如 ext4
    mv /path/to/executable /home/user/
    

5️⃣ 安全性機制 (AppArmorSELinux)

🔹 可能原因:
如果系統啟用了 AppArmorSELinux,可能限制了某些使用者對該執行檔的存取。

🔹 解決方法:

  • 檢查 AppArmor 狀態:
    aa-status
    
  • 如果發現有相關的限制,可以暫時停用:
    aa-complain /path/to/executable
    
  • 檢查 SELinux
    getenforce
    
    若為 Enforcing,可以嘗試:
    sudo setenforce 0  # 暫時關閉
    

6️⃣ 執行檔依賴的函式庫 (ldd 檢查)

🔹 可能原因:
如果執行檔是 ELF 二進制程式,但所需的函式庫(libraries)缺失,則執行時會出現 Permission denied

🔹 解決方法:

  1. 檢查執行檔的函式庫:
    ldd /path/to/executable
    
  2. 如果有 not found,則需要安裝缺失的函式庫。例如:
    apk add libc6-compat
    

7️⃣ 使用者帳戶沒有執行權限 (ulimit 限制)

🔹 可能原因:
系統管理員可能透過 ulimit 限制了某些使用者的執行權限。

🔹 解決方法:

  • 確認 ulimit 限制:
    ulimit -a
    
  • 如果 max user processes 設為 0,則可以調整:
    ulimit -u 1024
    

🔚 結論

若新使用者無法執行 777 檔案,建議按以下步驟逐一排查: ✅ 檢查 mount 是否有 noexec
確認檔案是否有正確的 Shebang (#!)
檢查 setfacl 是否限制該使用者
確認檔案系統是否支援執行權限 (df -T)
檢查 ldd 是否有缺失的函式庫
確認 AppArmorSELinux 是否干預
檢查 ulimit 是否限制執行權限

試試這些方法,看看是哪個因素導致的!🚀