linux常用工具命令 2021-11-17

查看內(nèi)核路由表(包含網(wǎng)關(guān)等信息)

netstat -rn or route -en

Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         9.134.xxx.1     0.0.0.0         UG        0 0          0 eth1
9.134.xxx.0     0.0.0.0         255.255.252.0   U         0 0          0 eth1
172.17.0.0      0.0.0.0         255.255.0.0     U         0 0          0 docker0
  • Destination. 目標網(wǎng)絡(luò)或目標主機。Destination 為 default(0.0.0.0)時,Gateway就表示默認網(wǎng)關(guān),所有數(shù)據(jù)都發(fā)到這個網(wǎng)關(guān)(這里是 9.134.xxx.1)
  • Gateway. 網(wǎng)關(guān)地址,0.0.0.0 表示當前記錄對應(yīng)的 Destination 跟本機在同一個網(wǎng)段,通信時不需要經(jīng)過網(wǎng)關(guān)
  • Genmask. Destination 字段的網(wǎng)絡(luò)掩碼,Destination 是主機時需要設(shè)置為 255.255.255.255,是默認路由時會設(shè)置為 0.0.0.0
  • Iface. 網(wǎng)卡名字,例如 eth0

Flags 含義:
U 路由是活動的
H 目標是個主機
G 需要經(jīng)過網(wǎng)關(guān)
R 恢復動態(tài)路由產(chǎn)生的表項
D 由路由的后臺程序動態(tài)地安裝
M 由路由的后臺程序修改
! 拒絕路由

以上結(jié)果等價于命令ip route show table main

配置路由規(guī)則和路由表

linux的路由配置由兩部分組成:路由規(guī)則routing rule路由表routing table

  • table. 一個table記錄了若干route(路線). the command ip route可以指定某個table寫入route
  • rule. rule選擇table中的route構(gòu)成routing policy. 也就是說,table中的route必須要被rule選中之后才會成為路由策略的一部分。the command ip rule manipulates rules in the routing policy database, and control the route selection algorithm.

ip rule & ip route 命令可以分別配置路由規(guī)則和路由表,而 route命令也可以配置路由表

linux路由表
linux可以自定義從1-252個路由表,另外linux自身維護了4個路由表:
0#表 系統(tǒng)保留表
253#表 default table 默認路由記錄都放在該表
254#表 main table 主路由表/傳統(tǒng)路由表,ip route若沒顯式指定表,則使用main table,而route -en也是查詢該表
255#表 local table 保存本地接口地址,廣播地址、NAT地址,例如在本機上執(zhí)行ssh 127.0.0.1時,就會參考這份路由表的內(nèi)容。該表由系統(tǒng)維護,用戶無法更改
(文件/etc/iproute2/rt_tables記錄了路由表名和表號的對應(yīng)關(guān)系)

在查看路由表之前,首先使用ip rule show命令來查看目前的路由規(guī)則使用了哪些路由表
ip rule refers rules in routing policy database
接著,再使用ip route show [table id | name]命令來查看相關(guān)路由表的內(nèi)容

[root@VM-165-116-centos ~]# ip rule show
0:      from all lookup local
32766:  from all lookup main
32767:  from all lookup default
[root@VM-165-116-centos ~]# 
[root@VM-165-116-centos ~]# ip route list table main
default via 9.aaa.164.1 dev eth1 proto dhcp metric 100 
9.aaa.164.0/22 dev eth1 proto kernel scope link src 9.aaa.165.116 metric 100 
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 
[root@VM-165-116-centos ~]# 
[root@VM-165-116-centos ~]# route -en
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         9.134.164.1     0.0.0.0         UG        0 0          0 eth1
...
[root@VM-165-116-centos ~]

解讀:

當前的路由規(guī)則將使用local/main/default這三個路由表
如果有數(shù)據(jù)包要送到9.aaa.164.0/22這個網(wǎng)段,就直接將數(shù)據(jù)包由eth1接口送出即可,而本機臨近這個網(wǎng)段的IP是9.aaa.165.116(這個就是本機eth1的IP)
如果有數(shù)據(jù)包要送到172.17.0.0/16這個網(wǎng)段,就直接將數(shù)據(jù)包由docker0接口送出即可,而本機臨近這個網(wǎng)段的IP是172.17.0.1(這個就是本機docker0的IP)
其他目的地的數(shù)據(jù)包,經(jīng)過eth1送往gateway 9.aaa.164.1,9.aaa.164.1就是我們在網(wǎng)絡(luò)配置中所設(shè)置的“默認網(wǎng)關(guān)”

下面實踐【配置路由表table 10】并【讓路由規(guī)則使用table 10】

[root@VM-165-116-centos ~]# ip route add default via 192.168.1.254 table 10 
Error: Nexthop has invalid gateway.  
[root@VM-165-116-centos ~]# ip route add default via 192.168.1.254 dev eth1 table 10
Error: Nexthop has invalid gateway.
[root@VM-165-116-centos ~]# ip route add 192.168.1.0/24 dev eth1 table 10   
[root@VM-165-116-centos ~]# ip route add default via 192.168.1.254 table 10 
[root@VM-165-116-centos ~]# ip route show table 10                         
default via 192.168.1.254 dev eth1 
192.168.1.0/24 dev eth1 scope link 
# 最初add default via 192.168.1.254 table 10失敗,是因為**內(nèi)核發(fā)現(xiàn)eth1和機器192.168.1.254并不聯(lián)通**(192.168.1.254 是隨便亂寫的IP,當然不聯(lián)通)
# 而我們先ip route add 192.168.1.0/24 dev eth1 table 10,**內(nèi)核不會檢查eth1與192.168.1.0/24網(wǎng)段是否互通**,而是內(nèi)核直接認為該記錄合法
# 在這個基礎(chǔ)上,內(nèi)核就認為192.168.1.254可由達,于是add default via 192.168.1.254也順利加入table10
[root@VM-165-116-centos ~]#
[root@VM-165-116-centos ~]# ip rule show
0:      from all lookup local
32766:  from all lookup main
32767:  from all lookup default
# 此時只是配置好了路由表,而沒有被rule應(yīng)用
[root@VM-165-116-centos ~]#
[root@VM-165-116-centos ~]# ip rule add from 192.168.1.10 table 10 
[root@VM-165-116-centos ~]# ip rule add to 168.95.1.1 table 10 
[root@VM-165-116-centos ~]# ip rule show                          
0:      from all lookup local
32764:  from all to 168.95.1.1 lookup 10
32765:  from 192.168.1.10 lookup 10
32766:  from all lookup main
32767:  from all lookup default
# 來自機器192.168.1.10和去往168.95.1.1的數(shù)據(jù)包,使用table 10的配置
[root@VM-165-116-centos ~]#
[root@VM-165-116-centos ~]# ip rule del from all to 168.95.1.1 # 刪除`from all to 168.95.1.1 lookup 10`
[root@VM-165-116-centos ~]# ip rule del table 10  # 刪除所有使用table10的規(guī)則
[root@VM-165-116-centos ~]# ip route flush table 10  # 清空table10的路由記錄

in addition:
從機器網(wǎng)卡發(fā)出的任何數(shù)據(jù)包,都需要一個路徑(route)作為依據(jù)
機器向網(wǎng)關(guān)發(fā)送數(shù)據(jù)包,【發(fā)往網(wǎng)關(guān)】這個路徑本身也是由routing rule / routing table決定的

假設(shè)機器eth1的IP是192.168.1.1,所連接的局域網(wǎng)網(wǎng)關(guān)為192.16那么8.1.254,給routing table配置這樣的route是非法的:
ip route add 192.168.1.0/24 via 192.168.1.254 dev eth1
這個命令表示,目的網(wǎng)絡(luò)是192.168.1.0/24則需要通過eth1先發(fā)往網(wǎng)關(guān)192.168.1.254
但是網(wǎng)關(guān)192.168.1.254本身也處在目標網(wǎng)絡(luò)192.168.1.0/24內(nèi),因此發(fā)往【192.168.1.254】需要通過eth1先發(fā)往【192.168.1.254】
so the kernel has no idea how to get to gateway 192.168.1.254
事實上,發(fā)往局域網(wǎng)內(nèi)的數(shù)據(jù)包不經(jīng)過網(wǎng)關(guān)

網(wǎng)絡(luò)抓包

tcpdump 
[-c count(抓幾個包)] 
[-s snaplen-bytes 每個包抓多長字節(jié)的數(shù)據(jù) -s64每包抓64字節(jié) -s0還原到默認]
[-i network-interface(指定網(wǎng)卡)] 
[-nn Don't convert protocol and port numbers etc. to names either.] 
[-v 讓抓包過程打印更多詳情]
[-w file(保存到文件)] 
[ expression (see pcap-filter)]

only packets that match expression will be processed by tcpdump
eg. tcpdump -i eth1 -s64 -c10 -w /filter.pcap tcp port 6666 and host 9.9.9.9

查看指定網(wǎng)卡IP

ifconfig eth1 |grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d "addr:"

查看dns配置

cat /etc/resolv.conf

netstat查看網(wǎng)絡(luò)連接/端口監(jiān)聽

netstat -tunlp是一個Linux系統(tǒng)管理員經(jīng)常使用的命令,可以展示當前正在監(jiān)聽或者連接的網(wǎng)絡(luò)連接和它們使用的進程。

具體含義如下:

"-t"參數(shù)顯示TCP連接。
"-u"參數(shù)顯示UDP連接。
"-n"參數(shù)禁用名稱解析,直接顯示IP地址和端口號。
"-l"參數(shù)顯示當前正在監(jiān)聽的所有連接。
"-p"參數(shù)顯示進程PID和名字。

因此,netstat -tunlp命令用于顯示所有正在監(jiān)聽或者連接的TCP和UDP端口,包括它們的IP地址和端口號,并且顯示處理網(wǎng)絡(luò)連接的進程的PID和名稱。

netstat類似于TCPView或者活動監(jiān)視器(Windows系統(tǒng))的功能。而lsof是用于查看系統(tǒng)中打開的文件("list open files")和相關(guān)進程的信息,其中也包括網(wǎng)絡(luò)連接。它可以列出當前系統(tǒng)中被打開的所有文件和網(wǎng)絡(luò)連接,不僅顯示網(wǎng)絡(luò)連接的信息,還可以查看文件相關(guān)的信息,比如文件名、文件描述符等

lsof看的是文件,netstat看的是網(wǎng)絡(luò)連接。由于lsof能夠查看打開文件描述符和端口號的詳細信息,因此在調(diào)試和排查網(wǎng)絡(luò)連接問題時,更經(jīng)常使用lsof命令。而netstat則更常用于監(jiān)控當前網(wǎng)絡(luò)連接的狀態(tài)

為什么lsof的結(jié)果顯示,F(xiàn)D相同,但是PID卻不同

eg.

root@centos:~# lsof -i:7500
COMMAND    PID USER   FD   TYPE    DEVICE SIZE/OFF NODE NAME
gunicorn 38756 root    7u  IPv4 894555171      0t0  TCP *:silhouette (LISTEN)
gunicorn 38757 root    7u  IPv4 894555171      0t0  TCP *:silhouette (LISTEN)
gunicorn 38758 root    7u  IPv4 894555171      0t0  TCP *:silhouette (LISTEN)
gunicorn 38759 root    7u  IPv4 894555171      0t0  TCP *:silhouette (LISTEN)
gunicorn 38760 root    7u  IPv4 894555171      0t0  TCP *:silhouette (LISTEN)
gunicorn 38761 root    7u  IPv4 894555171      0t0  TCP *:silhouette (LISTEN)
gunicorn 38762 root    7u  IPv4 894555171      0t0  TCP *:silhouette (LISTEN)
gunicorn 38764 root    7u  IPv4 894555171      0t0  TCP *:silhouette (LISTEN)
gunicorn 38765 root    7u  IPv4 894555171      0t0  TCP *:silhouette (LISTEN)
gunicorn 38766 root    7u  IPv4 894555171      0t0  TCP *:silhouette (LISTEN)
gunicorn 38767 root    7u  IPv4 894555171      0t0  TCP *:silhouette (LISTEN)
gunicorn 38768 root    7u  IPv4 894555171      0t0  TCP *:silhouette (LISTEN)
gunicorn 38770 root    7u  IPv4 894555171      0t0  TCP *:silhouette (LISTEN)

lsof命令的輸出中,同一文件描述符(FD)對應(yīng)的進程ID通常是唯一的。但在某些情況下,可能會出現(xiàn)相同的文件描述符對應(yīng)不同的進程ID的情況,這通常發(fā)生在:

  • 程序使用了“fork()”系統(tǒng)調(diào)用創(chuàng)建了子進程,而子進程沒有關(guān)閉對應(yīng)的文件句柄,在父進程和子進程都能夠訪問同一個文件描述符的情況下,會存在同一個文件描述符對應(yīng)多個進程ID的情況。

  • 程序使用了共享內(nèi)存或者共享套接字,這也會導致同一文件描述符對應(yīng)不同的進程PID。

在這些情況下,可以通過查看"TYPE"字段,來判斷同一文件描述符對應(yīng)的是同一種文件類型,同一種類型的文件描述符才可能被多個不同的進程使用。

配置系統(tǒng)http/https代理

部分linux服務(wù)器處于內(nèi)網(wǎng)或者受限制的網(wǎng)絡(luò)環(huán)境下,想與外網(wǎng)進行http/https通信只能通過nat或者加proxy的方式。nat服務(wù)器有網(wǎng)段的限制,而http/https proxy代理則沒有
linux設(shè)置http/https proxy的方法,在當前shell、或者/etc/bashrc、或者/etc/profile中添加如下環(huán)境變量

export http_proxy=http://1.1.1.1:8082
export https_proxy=http://1.1.1.1:8082

配置某些域名禁用代理

在當前shell、或者/etc/bashrc、或者/etc/profile中添加如下環(huán)境變量

export no_proxy='a.test.com,127.0.0.1,2.2.2.2'

vim內(nèi)查找目標

vim file后,鍵入/進入查找模式
/后接需要查找的目標

  • 支持大小寫敏感(默認就是大小寫敏感)
    在查找模式中,加入\c表示大小寫不敏感查找,\C表示大小寫敏感查找
    例如:
/foo\c 大小寫不敏感
  • 支持正則表達式
    例如:
/^foo$\c 
  • 對于多個結(jié)果,鍵入n跳轉(zhuǎn)到下一個,鍵入N跳轉(zhuǎn)到下一個

根據(jù)文件名查找當前文件夾及其子文件夾的所有文件

find . -type f -name "regular_expression"

從文件中查找匹配pattern的行

grep -e “regular_expression" target_file
Eg.

grep -e "message.*已經(jīng)分配給ID為" ./do_reservation.log
               "message" : "IP[10.0.128.4]已經(jīng)分配給ID為[574917731]的服務(wù)器",
               "message" : "IP[10.0.130.20]已經(jīng)分配給ID為[574918748]的服務(wù)器",
# 按:分割并且輸出第2部分
grep -e "message.*已經(jīng)分配給ID為" ./do_reservation.log | cut -d ":" -f 2
  "IP[10.0.128.4]已經(jīng)分配給ID為[574917731]的服務(wù)器",
  "IP[10.0.130.20]已經(jīng)分配給ID為[574918748]的服務(wù)器",
# 使用 -o --only-matching Prints only the matching part of the lines. 僅輸出IP地址
grep -e "message.*已經(jīng)分配給ID為" ./do_reservation.log | cut -d ":" -f 2 | grep -E -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
or
grep -e "message.*已經(jīng)分配給ID為" ./do_reservation.log | cut -d ":" -f 2 | grep -E -o '([0-9]{1,3}[\.]){3}[0-9]{1,3}'

10.0.128.4
10.0.130.20

目錄跳轉(zhuǎn) pushd popd

命令行的當前目錄等于目錄棧棧頂目錄

[user@server /usr/ports] $ pushd /etc
/etc /usr/ports    ->pushd后當前目錄棧的情況
[user@server /etc] $ popd
/usr/ports    ->popd后當前目錄棧的情況
[user@server /usr/ports] $

追蹤dns查詢過程 dig(domain information groper)

dns的查詢過程:DNS客戶端和本地名稱服務(wù)器是遞歸查詢,而本地名稱服務(wù)器和其他名稱服務(wù)器之間是迭代查詢。Most DNS administrators use dig command to troubleshoot DNS problems
common command: dig [Options] [TYPE] [Domain_Name]

dig targetdomain

[root@VM-165-116-centos workspace]# dig stackoverflow.com 

; <<>> DiG 9.10.6 <<>> stackoverflow.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 17243
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4000
;; QUESTION SECTION:  # -> 顯示查詢內(nèi)容,查詢stackoverflow.com的A記錄
;stackoverflow.com.             IN      A

;; ANSWER SECTION:    # -> 顯示dns的應(yīng)答結(jié)果。stackoverflow.com有4個A記錄,且time-to-live都是299秒(這個時間內(nèi)無需重新查詢)
stackoverflow.com.      299     IN      A       151.101.65.69
stackoverflow.com.      299     IN      A       151.101.193.69
stackoverflow.com.      299     IN      A       151.101.129.69
stackoverflow.com.      299     IN      A       151.101.1.69

;; Query time: 655 msec
;; SERVER: 10.123.119.98#53(10.123.119.98)  # -> 本機的dns server是10.123.119.98,dns服務(wù)端口為53
;; WHEN: Thu Jan 27 17:36:48 CST 2022
;; MSG SIZE  rcvd: 115     # -> 響應(yīng)字節(jié)數(shù)115

dig +trace targetdomain
參考https://www.2daygeek.com/dig-command-check-find-dns-records-lookup-linux/

清除dns緩存

What is DNS cache and what it Does?

The DNS cache is a temporary database maintained by the computer’s operating system.
It stores information about previous DNS lookups (like information on recently visited websites and other web domains).
This will quickly resolve DNS queries when you visit the cached website by getting details from the local DNS database instead of the actual DNS server.

How to Clear/Flush the DNS Cache on Linux

By default, DNS caching is not installed or enabled at the OS level, but if you have installed any of the caching services listed below, use the appropriate commands to flush them.

Below is a list of the major DNS cache services used in the Linux operating system.

systemd Resolved Service
nscd DNS Cache
dnsmasq DNS Cache
BIND server DNS Cache

systemd Resolved Service

Most modern Linux operating systems use systemd as the default init proccess(當前大部分linux os 使用systemd作為默認的init程序), so use the command below to flush the DNS cache.

$ sudo systemctl is-active systemd-resolve.service   # check if the DNS cache service is active on your system.
$ sudo systemd-resolve --flush-caches 

nscd DNS Cache

nscd stands for name service cache daemon, nscd is a daemon that provides a cache for the most common name service requests. The default configuration file located at /etc/nscd.conf. 里面配置了enable-cache的類型、time-to-live、max-db-size等參數(shù),決定了哪些信息需要被cached、保持時長、cached數(shù)據(jù)庫大小等

$ sudo systemctl restart nscd   # 重啟以清理緩存

dnsmasq DNS Cache

Dnsmasq is a lightweight, small footprint, easy to configure, DNS forwarder and DHCP server. It is designed to provide DNS and optionally, DHCP, to a small network & suitable for resource constrained routers and firewalls. It can serve the names of local machines which are not in the global DNS. It is designed for personal computer use and small size networks, not for big networks. dnsmasq為私有dns服務(wù)

$ sudo systemctl restart dnsmasq   # 重啟以清理緩存

BIND Server DNS Cache

BIND stands for “Berkeley Internet Name Domain”. The most widely used Name Server Software, BIND is open source software that implements the Domain Name System (DNS) protocols for the Internet. BIND is by far the most widely used DNS software on the Internet, providing a robust and stable platform. 通過起named service來提供dns服務(wù)

$ sudo systemctl restart named   # 使用重啟服務(wù)的方式,flush the BIND server DNS cache on Systemd-based Linux systems.
or
$ sudo rndc flushname 2daygeek.com   # rndc, named的服務(wù)管理工具,指定刪除某個域名的dns緩存

很多dns服務(wù)都通過重啟來實現(xiàn)清理緩存的目的

關(guān)于/etc/hosts和nslookup

nslookup only does proper DNS resolution, which is significantly different from the Name Service Switch subsystem that your other applications use; that is to say nslookup ignores /etc/hosts and mDNS.

To test local dns resolutions after modifying /etc/hosts, use something that uses NSS. ping <hostname> for example

修改環(huán)境變量

  • 永久生效:
    • 系統(tǒng)環(huán)境變量
      vim /etc/profile
      source /etc/profile

    • 用戶shell環(huán)境變量
      Linux系統(tǒng)中有很多種類的shell,不管是bash,sh,dash,都會有一個~/.bashrc的隱藏文件,該文件存在于用戶的家目錄,是每一個用戶運行shell時執(zhí)行的文件,當shell被打開時,該文件被讀取。這個文件主要保存?zhèn)€人用戶的一些個性化的設(shè)置
      vim ~/.bashrc
      source ~/.bashrc

cat ~/.bashrc
# .bashrc

# User specific aliases and functions
# for TencentOS, remove these aliases
#alias rm='rm -i'
#alias cp='cp -i'
#alias mv='mv -i'

# Source global definitions   ->source用戶的~/.bashrc前,會先source一下全局bashrc
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi
export PATH="$PATH:$HOME/.ft:$GOPATH/bin"
  • 當前shell臨時生效的變量
    eg. export PATH=$PATH:/opt/au1200_rm/build_tools/bin. 當shell退出的時候,這些變量就會失效
    注意:
    • do not use sudo before export. Because "export" is a "shell built-in", not a "command"(a command is an executable binary on the host). "sudo" runs commands. That's why it can't find a command when you try to "sudo export".
    • take care of the variable scope in shell. shell是一個進程,擁有獨立的內(nèi)存空間,進程間數(shù)據(jù)不可見
      一個shell中用export定義的環(huán)境變量只會對當前shell及其子shell有效,而無法作用于父shell。shell結(jié)束之后,變量生命周期結(jié)束

內(nèi)核

一個os發(fā)行版可以支持多個kennel
安裝內(nèi)核 yum install 內(nèi)核,在grab.conf中配置使用的內(nèi)核

非交互式修改用戶密碼

chpasswd命令

[root@VM-165-116-centos sbin]# chpasswd -h
Usage: chpasswd [options]

Options:
  -c, --crypt-method METHOD     the crypt method (one of NONE DES MD5 SHA256 SHA512)
  -e, --encrypted               supplied passwords are encrypted
  -h, --help                    display this help message and exit
  -m, --md5                     encrypt the clear text password using
                                the MD5 algorithm
  -R, --root CHROOT_DIR         directory to chroot into
  -s, --sha-rounds              number of SHA rounds for the SHA*
                                crypt algorithms

[root@VM-165-116-centos sbin]# echo "username":"newpwd" | /usr/sbin/chpasswd -c MD5

curl 獲取時延詳情

-w, --write-out <format>
Make curl display information on stdout after a completed transfer

-s, --silent
Silent or quiet mode. Don't show progress meter or error messages. Makes Curl mute. It will still
output the data you ask for, potentially even to the terminal/stdout unless you redirect it
.

curl https://www.baidu.com --connect-timeout 5 -m 10 -o /dev/null -s -w time_namelookup:%{time_namelookup},time_connect:%{time_connect},time_appconnect:%{time_appconnect},time_starttransfer:%{time_starttransfer},time_total:%{time_total}"\n"

All variables are specified as %{variable_name} and to output a normal % you just write them as %%. You can output a newline by using \n, a carriage return with \r and a tab space with \t.

login shell and non-login shell

A login shell is the first process that executes under your user ID when you log in for an interactive session. The login process tells the shell to behave as a login shell with a convention: passing argument 0, which is normally the name of the shell executable, with a - character prepended (e.g. -bash whereas it would normally be bash.
Login shells typically read a file that does things like setting environment variables:
/etc/profile and
~/.profile for the traditional Bourne shell,
~/.bash_profile additionally for bash,
/etc/zprofile and ~/.zprofile for zsh,
/etc/csh.login and ~/.login for csh,
etc.

to tell if you are in a login shell:

prompt> echo $0
-bash # "-" is the first character. Therefore, this is a login shell.

prompt> echo $0
bash # "-" is NOT the first character. This is NOT a login shell.

When you log in on a text console, or through SSH, or with su -, you get an interactive login shell. When you log in in graphical mode (on an X display manager), you don't get a login shell, instead you get a session manager or a window manager.

When you start a shell in a terminal in an existing session (screen, X terminal, Emacs terminal buffer, a shell inside another, etc.), you get an interactive, non-login shell.
That shell might read a shell configuration file:
~/.bashrc for bash,
/etc/zshrc and ~/.zshrc for zsh,
/etc/csh.cshrc and ~/.cshrc for csh,
etc
【各種rc】

rc refers to 'run commands'

su (switch user with login shell or non-login shell)

The su (short for substitute or switch user) utility allows you to run commands with another user’s privileges(the fact is to run commands with substitute user and group ID)

For backward compatibility su defaults to not change the current directory and to only set the environment variables HOME and SHELL (plus USER and LOGNAME if the target user is not root).

It is recommended to always use the --login option (instead it's shortcut -) to avoid side effects caused by mixing environments. This makes the shell a login shell with an environment very similar to a real login and changes the current directory

-, -l, --login
              Starts the shell as login shell with an environment similar to a real login:

                 o      clears all environment variables except for TERM

                 o      initializes the environment variables HOME, SHELL, USER, LOGNAME, PATH

                 o      changes to the target user's home directory

                 o      sets argv[0] of the shell to '-' in order to make the shell a login shell

redirecton

What does " 2>&1 " mean?
File descriptor 1 is the standard output (stdout).
File descriptor 2 is the standard error (stderr).

  • At first, 2>1 may look like a good way to redirect stderr to stdout. However, it will actually be interpreted as "redirect stderr to a file named 1".
  • & indicates that what follows and precedes is a file descriptor(like a pointer in C), and not a filename. Thus, we use 2>&1. Consider >& to be a redirect merger operator.

至于為什么不是&2>&1 2> &1,我也不知道

bash set

set 顧名思義,可以理解為對shell解釋器本身的行為進行控制,如訪問不存在的變量是否報錯,運行錯誤是否自動exit等。有點類似于sysctl去控制內(nèi)核的行為
eg.
set -e e stands for errexit
set -e 根據(jù)命令返回值來判斷一個命令是否運行失??;只要運行失敗發(fā)生錯誤,且不在shell的正常handle范圍,就終止執(zhí)行并且退出當前函數(shù)或者當前shell

Exit immediately if a pipeline (which may consist of a single simple command), a list, or a compound command, exits with a non-zero status

注意,以下幾種情況不會exit,它們屬于shell正常handle范圍
The shell does not exit if the command that fails is

  • part of the command list immediately following a while or until keyword, (控制邏輯的一部分)
  • part of the test following the if or elif reserved words, (判斷邏輯的一部分)
  • part of any command executed in a && or || list except the command following the final && or || (非&& || 的最后一個命令,這種情況屬于shell的正常handle范圍:例如 A && B,A fails后,shell自動停止向后執(zhí)行B;A || B,A fails后,shell自動向后執(zhí)行B,保證||語義正確)
  • any command in a pipeline but the last(非管道的最后一個命令)
  • or if the command's return value is being inverted with !
[root@VM-165-116-centos ~]# set -e; foo | echo hhh 
hhh
bash: foo: command not found...
[root@VM-165-116-centos ~]# 
[root@VM-165-116-centos ~]# set -e; foo && echo hhh
bash: foo: command not found...
[root@VM-165-116-centos ~]# echo $?
127
[root@VM-165-116-centos ~]# 
[root@VM-165-116-centos ~]# set -e; echo hhh && foo
hhh
bash: foo: command not found...

Terminal Disconnect.
exitCode: 127
reason: no reason


Press <Enter> to reconnect...

為什么會有set -e —— 關(guān)鍵是遇錯自動Abort

當一個shell腳本在運行中出現(xiàn)錯誤,我們不期望腳本繼續(xù)運行下去而是直接退出,我們可以通過在每條命令或者關(guān)鍵命令的最后加上|| exit 1來實現(xiàn)。但是這樣一來,shell腳本會變得冗余并且丑陋。于是,shell的開發(fā)者專門針對“錯誤捕捉”開發(fā)了set -e
Its goal was to cause the shell to abort any time an error occurred, so you don't have to put || exit 1 after each important command
The developers of the original Bourne shell decided that they would create a feature that would allow the shell to check the exit status of every command that it runs, and abort if one of them returns non-zero. Thus, set -e was born

為什么shell需要這個略微奇葩的錯誤處理機制

歸根到底,shell是低可控性的腳本語言,發(fā)生什么都是有可能的,所以干脆搞一個報錯退出
低可控性體現(xiàn)在兩個方面:

  1. 最主要的原因就是偏底層,其錯誤信息基本上只依靠return code,無法提供更豐富的錯誤信息,導致無法較方便地實現(xiàn)更上層的錯誤處理。除非每行命令后都進行if [ $? == 0 ]判斷
  2. shell腳本調(diào)用了大量的external programs,你無法知道這些external programs會如何返回它的return code. 例如,shell 的builtIn let arg [arg ...] If the last arg evaluates to 0, let returns 1; 0 is returned otherwise. 所以i=0; let i++; 會將i自增1,但是i++本身evaluates to 0,因此let i++returncode是 1,等于是邏輯全部正常執(zhí)行,但是返回了“錯誤”

番外:

In modern high-level languages, most tasks are performed by using the language's builtin commands or features. The language knows whether (for example) you tried to divide by zero, or open a file that you can't open, and so on. It can take action based on this knowledge.

But in the shell, most of the tasks you actually care about are done by external programs. The shell can't tell whether an external program encountered something that it considers an error -- and even if it could, it wouldn't know whether the error is an important one, worthy of aborting the entire program, or whether it should carry on.

Exercise 1: why doesn't this example print anything?

#!/usr/bin/env bash
set -e
i=0
let i++ # returncode is 1 and exit immediately
echo "i is $i"

Exercise 2: why does this one sometimes appear to work? In which versions of bash does it work, and in which versions does it fail?

#!/usr/bin/env bash
set -e
i=0
((i++))
echo "i is $i"

Exercise 3: why aren't these two scripts identical?

#!/usr/bin/env bash
set -e
test -d nosuchdir && echo no dir # err in test is ignored by set -e
echo survived # echo successfully
#!/usr/bin/env bash
set -e
f() { test -d nosuchdir && echo no dir; }
f # exit immediately
echo survived 

Exercise 4: why aren't these two scripts identical?

set -e
f() { test -d nosuchdir && echo no dir; }
f # exit immediately because if there is no return in a func, the func use the last command's return code as its return code 
echo survived
set -e
f() { if test -d nosuchdir; then echo no dir; fi; }
f
echo survived # echo successfully

more for https://wangdoc.com/bash/set, http://mywiki.wooledge.org/BashFAQ/105

subnet mask 和 umask

subnet mask中1表示位有效,0表示位無效,就像遮蔽一樣
ip 與 subnet mask 按位與,得到子網(wǎng)地址

而umask和subnet mask表示遮蔽的方式是相反的,1表示遮蔽(這真是迷,subnet mask更容易接受)
因此,要用【按位與】去計算最終文件權(quán)限,必須先對umask取反
如,文件的原始權(quán)限是666,root的默認umask=0022(高位0忽略,有用的就是022)
則最終文件權(quán)限計算如下:

  110 110 110 (6 6 6)
& 111 101 101 (~0 ~2 ~2)  # ~0 = 111,表示無遮蔽;~2 = 101,表示遮蔽中間位
---------------------------
  110 100 100 (6 4 4)

download using wget or curl

wget --connect-timeout 10 -t2 https://mirrors.tencent.com/repository/generic/xxx/xxx.tgz [-O xxx.tgz]
or
curl -s --resolve "mirrors.tencent.com:80:100.115.83.221" --resolve "mirrors.tencent.com:80:9.2.87.192" http://mirrors.tencent.com/repository/generic/xxx/xxx.tgz --connect-timeout 5 [-o xxx.tgz]

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容