Computer >> Máy Tính >  >> Lập trình >> Lập trình BASH

Mẹo Bash cho hàng ngày tại dòng lệnh

Là trình bao mặc định cho nhiều biến thể Linux và Unix, Bash bao gồm nhiều tính năng ít được sử dụng, vì vậy thật khó để quyết định những gì cần thảo luận. Cuối cùng, tôi quyết định tập trung vào các mẹo Bash giúp các hoạt động hàng ngày trở nên dễ dàng hơn.

Là một nhà tư vấn, tôi nhận thấy rất nhiều môi trường và phong cách làm việc đa dạng. Tôi đã rút ra kinh nghiệm này để thu hẹp các mẹo thành bốn danh mục lớn:Thủ thuật đầu cuối và dòng, điều hướng và tệp, lịch sử và các lệnh hữu ích. Những phân loại này hoàn toàn tùy ý và phục vụ nhiều hơn để sắp xếp suy nghĩ của riêng tôi hơn là bất kỳ loại phân loại dứt khoát nào. Nhiều mẹo bao gồm ở đây có thể chủ quan phù hợp với nhiều danh mục.

Không cần nói thêm, đây là một số thủ thuật Bash hữu ích nhất mà tôi đã gặp.

Làm việc với lịch sử Bash

Một trong những cách tốt nhất để tăng năng suất của bạn là học cách sử dụng lịch sử Bash hiệu quả hơn. Với ý nghĩ đó, có lẽ một trong những điều chỉnh quan trọng nhất mà bạn có thể thực hiện trong môi trường nhiều người dùng là bật histappend tùy chọn cho trình bao của bạn. Để làm điều đó, chỉ cần chạy lệnh sau:

shopt -s histappend 

Điều này cho phép nhiều phiên đầu cuối ghi vào lịch sử cùng một lúc. Trong hầu hết các môi trường, tùy chọn này không đã được kích hoạt. Điều đó có nghĩa là lịch sử thường bị mất nếu bạn có nhiều hơn một phiên Bash đang mở (cục bộ hoặc qua SSH).

Một tác vụ phổ biến khác là lặp lại lệnh cuối cùng với sudo . Ví dụ:giả sử bạn muốn tạo một thư mục mkdir /etc/ansible/facts.d . Trừ khi bạn root, lệnh này sẽ không thành công. Từ những gì tôi quan sát được, hầu hết người dùng đều nhấn up mũi tên, cuộn đến đầu dòng và thêm sudo yêu cầu. Co một cach dê dang hơn. Chỉ cần chạy lệnh như sau:

sudo !!

Bash sẽ chạy sudo và sau đó là toàn bộ lệnh trước đó. Đây chính xác là nó trông như thế nào khi chạy theo trình tự:

[user@centos ~]$ mkdir -p /etc/ansible/facts.d
mkdir: cannot create directory ‘/etc/ansible’: Permission denied

[user@centos ~]$ sudo !!
sudo mkdir -p /etc/ansible/facts.d

Khi !! được chạy, toàn bộ lệnh được gửi lại tới thiết bị đầu cuối để bạn biết những gì vừa được thực thi.

Tương tự nhưng được sử dụng ít thường xuyên hơn là !* đường tắt. Điều này cho Bash biết rằng bạn muốn có tất cả * đối số * từ lệnh trước đó được lặp lại trong lệnh hiện tại. Điều này có thể hữu ích cho một lệnh có nhiều đối số mà bạn muốn sử dụng lại. Một ví dụ đơn giản là tạo một loạt các tệp và sau đó thay đổi các quyền trên chúng:

[user@centos tmp]$ touch file1 file2 file3 file4
[user@centos tmp]$ chmod 777 !*
chmod 777 file1 file2 file3 file4

Nó chỉ hữu ích trong một số trường hợp cụ thể, nhưng nó có thể giúp bạn tiết kiệm một số lần gõ phím.

Nói về cách lưu các lần gõ phím, hãy nói về việc tìm kiếm các lệnh trong lịch sử của bạn. Hầu hết người dùng sẽ làm điều gì đó như sau:

history |grep <some command>

Tuy nhiên, có một cách dễ dàng hơn để tìm kiếm lịch sử của bạn. Nếu bạn nhấn

ctrl + r

Bash sẽ thực hiện tìm kiếm ngược lại lịch sử của bạn. Khi bạn bắt đầu nhập, kết quả sẽ bắt đầu xuất hiện. Ví dụ:

(reverse-i-search)`hist': shopt -s histappend

Trong ví dụ trên, tôi đã nhập hist và nó khớp với shopt lệnh mà chúng tôi đã đề cập trước đó. Nếu bạn tiếp tục nhấn ctrl + r , Bash sẽ tiếp tục tìm kiếm ngược qua tất cả các trận đấu khác.

Thủ thuật cuối cùng của chúng tôi không phải là một thủ thuật nhiều như một lệnh hữu ích mà bạn có thể sử dụng để đếm và hiển thị các lệnh được sử dụng nhiều nhất trong lịch sử của mình.

[user@centos tmp]$ history | awk 'BEGIN {FS="[ \t]+|\\|"} {print $3}' | sort | uniq -c | sort -nr | head 
81 ssh
50 sudo
46 ls
45 ping
39 cd
29 nvidia-xrun
20 nmap
19 export

Trong ví dụ này, bạn có thể thấy rằng ssh cho đến nay là lệnh được sử dụng nhiều nhất trong lịch sử của tôi vào thời điểm hiện tại.

Điều hướng và đặt tên tệp

Bạn có thể đã biết rằng nếu bạn nhập lệnh, tên tệp hoặc tên thư mục, bạn có thể nhấn vào tab tab phím một lần để hoàn thành từ ngữ cho bạn. Điều này hoạt động nếu có một kết hợp chính xác duy nhất. Tuy nhiên, bạn có thể không biết điều đó nếu bạn nhấn tab hai lần, nó sẽ hiển thị cho bạn tất cả các kết quả phù hợp dựa trên những gì bạn đã nhập. Ví dụ:

[user@centos tmp]$ cd /lib <tab><tab>
lib/ lib64/

Điều này có thể rất hữu ích cho việc điều hướng hệ thống tệp. Một thủ thuật hữu ích khác là bật cdspell trong vỏ của bạn. Bạn có thể thực hiện việc này bằng cách phát hành shopt -s cdspell yêu cầu. Điều này sẽ giúp sửa lỗi chính tả của bạn:

[user@centos etc]$ cd /tpm
/tmp
[user@centos tmp]$ cd /ect
/etc

Nó không hoàn hảo, nhưng mọi thứ đều hữu ích!

Khi bạn đã thay đổi thành công các thư mục, nếu bạn cần quay lại thư mục trước đó của mình thì sao? Đây không phải là vấn đề lớn nếu bạn không tìm hiểu sâu về cây thư mục. Nhưng nếu bạn đang ở trong một đường dẫn khá sâu, chẳng hạn như /var/lib/flatpak/exports/share/applications/ , bạn có thể nhập:

cd /va<tab>/lib/fla<tab>/ex<tab>/sh<tab>/app<tab>

May mắn thay, Bash nhớ thư mục trước của bạn và bạn có thể quay lại đó bằng cách chỉ cần gõ cd - . Đây là những gì nó sẽ trông như thế nào:

[user@centos applications]$ pwd
/var/lib/flatpak/exports/share/applications

[user@centos applications]$ cd /tmp
[user@centos tmp]$ pwd
/tmp

[user@centos tmp]$ cd -
/var/lib/flatpak/exports/share/applications

Đó là tất cả tốt và tốt, nhưng điều gì sẽ xảy ra nếu bạn có một loạt các thư mục mà bạn muốn điều hướng dễ dàng bên trong? Bash cũng có bạn ở đó. Có một biến bạn có thể đặt sẽ giúp bạn điều hướng hiệu quả hơn. Đây là một ví dụ:

[user@centos applications]$ export CDPATH='~:/var/log:/etc'
[user@centos applications]$ cd hp
/etc/hp

[user@centos hp]$ cd Downloads
/home/user/Downloads

[user@centos Downloads]$ cd ansible
/etc/ansible

[user@centos Downloads]$ cd journal
/var/log/journal

Trong ví dụ trên, tôi đặt thư mục chính của mình (được biểu thị bằng dấu ngã:~ ), /var/log/etc . Bất kỳ thứ gì ở cấp cao nhất của các thư mục này sẽ được tự động điền vào khi bạn tham khảo chúng. Các thư mục không nằm ở cơ sở của các thư mục được liệt kê trong CDPATH sẽ không được tìm thấy. Ví dụ:nếu thư mục bạn đang theo dõi là /etc/ansible/facts.d/ điều này sẽ không hoàn thành bằng cách nhập cd facts.d . Điều này là do trong khi thư mục ansible được tìm thấy trong /etc , facts.d không phải. Do đó, CDPATH rất hữu ích để lên đầu cây mà bạn truy cập thường xuyên, nhưng nó có thể khó quản lý khi bạn đang duyệt một cấu trúc thư mục lớn.

Cuối cùng, hãy nói về hai trường hợp sử dụng phổ biến mà mọi người đều làm tại một số điểm:Thay đổi phần mở rộng tệp và đổi tên tệp. Thoạt nhìn, điều này nghe có vẻ giống nhau, nhưng Bash cung cấp một số thủ thuật khác nhau để thực hiện những nhiệm vụ này.

Mặc dù đây có thể là một hoạt động "tồi tệ và bẩn thỉu", hầu hết người dùng tại một số thời điểm cần tạo một bản sao nhanh của tệp mà họ đang làm việc. Hầu hết sẽ sao chép chính xác tên tệp và chỉ cần thêm một phần mở rộng tệp như .old hoặc .bak . Có một phím tắt nhanh cho việc này trong Bash. Giả sử bạn có tên tệp như spideroak_inotify_db.07pkh3 mà bạn muốn giữ một bản sao. Bạn có thể nhập:

cp spideroak_inotify_db.07pkh3 spideroak_inotify_db.07pkh3.bak

Bạn có thể thực hiện nhanh việc này bằng cách sử dụng các thao tác sao chép / dán, sử dụng tab hoàn chỉnh, có thể sử dụng một trong các phím tắt để lặp lại một đối số hoặc chỉ cần gõ toàn bộ. Tuy nhiên, lệnh dưới đây sẽ hoạt động nhanh hơn khi bạn đã quen với việc gõ nó:

cp spideroak_inotify_db.07pkh3{,.old}

Điều này (như bạn có thể đoán) sao chép tệp bằng cách thêm .old phần mở rộng tệp vào tệp. Điều đó thật tuyệt, bạn có thể nói, nhưng tôi muốn đổi tên một số lượng lớn tệp cùng một lúc. Chắc chắn, bạn có thể viết một vòng lặp for để đối phó với những điều này (và trên thực tế, tôi thường làm điều này vì những thứ phức tạp) nhưng tại sao bạn lại làm vậy khi có một tiện ích hữu ích được gọi là rename ? Có một số khác biệt trong cách sử dụng tiện ích này giữa Debian / Ubuntu và CentOS / Arch. Đổi tên dựa trên Debian sử dụng cú pháp giống SED:

user@ubuntu-1604:/tmp$ for x in `seq 1 5`; do touch old_text_file_${x}.txt; done

user@ubuntu-1604:/tmp$ ls old_text_file_*
old_text_file_1.txt old_text_file_3.txt old_text_file_5.txt
old_text_file_2.txt old_text_file_4.txt

user@ubuntu-1604:/tmp$ rename 's/old_text_file/shiney_new_doc/' *.txt

user@ubuntu-1604:/tmp$ ls shiney_new_doc_*
shiney_new_doc_1.txt shiney_new_doc_3.txt shiney_new_doc_5.txt
shiney_new_doc_2.txt shiney_new_doc_4.txt

Trên hộp CentOS hoặc Arch, nó sẽ giống như sau:

[user@centos /tmp]$ for x in `seq 1 5`; do touch old_text_file_${x}.txt; done

[user@centos /tmp]$ ls old_text_file_*
old_text_file_1.txt old_text_file_3.txt old_text_file_5.txt
old_text_file_2.txt old_text_file_4.txt

[user@centos tmp]$ rename old_text_file centos_new_doc *.txt

[user@centos tmp]$ ls centos_new_doc_*
centos_new_doc_1.txt centos_new_doc_3.txt centos_new_doc_5.txt
centos_new_doc_2.txt centos_new_doc_4.txt

Liên kết khóa Bash

Bash có rất nhiều phím tắt được tích hợp sẵn. Bạn có thể tìm thấy danh sách chúng bằng cách nhập bind -p . Tôi nghĩ sẽ hữu ích nếu làm nổi bật một số, mặc dù một số có thể nổi tiếng.

  • ctrl + _ (hoàn tác)
  • ctrl + t (hoán đổi hai ký tự)
  • ALT + t (hoán đổi hai từ)
  • ALT +. (in đối số cuối cùng từ lệnh trước)
  • ctrl + x + * (mở rộng hình cầu / sao)
  • ctrl + mũi tên (chuyển tiếp một từ)
  • ALT + f (chuyển tiếp một từ)
  • ALT + b (lùi lại một từ)
  • ctrl + x tiếp theo là ctrl + e (mở chuỗi lệnh trong trình chỉnh sửa để bạn có thể chỉnh sửa nó trước khi thực thi)
  • ctrl + e (di chuyển con trỏ đến cuối)
  • ctrl + a (di chuyển con trỏ để bắt đầu)
  • ctrl + xx (chuyển sang đầu đối diện của dòng)
  • ctrl + u (cắt mọi thứ trước con trỏ)
  • ctrl + k (cắt mọi thứ sau con trỏ)
  • ctrl + y (dán từ bộ đệm)
  • ctrl + l (chữ L viết thường, xóa màn hình)

Tôi sẽ không thảo luận về những cái rõ ràng hơn. Tuy nhiên, một số phím tắt hữu ích nhất mà tôi đã tìm thấy là những phím tắt cho phép bạn xóa các từ (hoặc các phần văn bản) và hoàn tác chúng. Giả sử bạn định dừng một loạt dịch vụ bằng systemd , nhưng bạn chỉ muốn bắt đầu một vài trong số chúng sau khi một số hoạt động đã hoàn thành. Bạn có thể làm điều gì đó như sau:

systemctl stop httpd mariadb nfs smbd
<hit the up button to get the previous command>
<use 'ctrl + w' to remove the unwanted arguments>

Nhưng điều gì sẽ xảy ra nếu bạn loại bỏ một quá nhiều? Không thành vấn đề — chỉ cần sử dụng ctrl + _ để hoàn tác lần chỉnh sửa cuối cùng.

Các lệnh cắt khác cho phép bạn nhanh chóng xóa mọi thứ từ con trỏ đến cuối hoặc đầu dòng (sử dụng Ctrl + kCtrl + u , tương ứng). Điều này có lợi ích bổ sung là đặt văn bản đã cắt vào bộ đệm đầu cuối để bạn có thể dán nó sau này (sử dụng ctrl + y ). Ở đây khó thể hiện các lệnh này, vì vậy tôi đặc biệt khuyến khích bạn nên tự mình thử chúng.

Cuối cùng nhưng không kém phần quan trọng, tôi muốn đề cập đến một tổ hợp phím hiếm khi được sử dụng có thể cực kỳ tiện dụng trong các môi trường hạn chế như vùng chứa. Nếu bạn từng thấy lệnh bị cắt xén bởi đầu ra trước đó, có một giải pháp:Nhấn ctrl + x + ctrl + e sẽ mở lệnh trong bất kỳ trình soạn thảo nào được đặt trong biến môi trường EDITOR. Điều này sẽ cho phép bạn chỉnh sửa một lệnh dài hoặc bị cắt xén trong trình soạn thảo văn bản mà (có khả năng) có thể bao bọc văn bản. Lưu công việc của bạn và thoát, giống như khi bạn làm việc trên một tệp bình thường, sẽ thực hiện lệnh khi rời khỏi trình chỉnh sửa.

Các mẹo khác

Bạn có thể thấy rằng việc hiển thị màu sắc trong Bash shell có thể nâng cao trải nghiệm của bạn. Nếu bạn đang sử dụng một phiên không được bật chế độ tô màu, dưới đây là một loạt lệnh bạn có thể đặt trong .bash_profile của mình để thêm màu sắc cho phiên của bạn. Những điều này khá đơn giản và không cần giải thích sâu:

# enable colors
eval "`dircolors -b`"

# force ls to always use color and type indicators
alias ls='ls -hF --color=auto'

# make the dir command work kinda like in windows (long format)
alias dir='ls --color=auto --format=long'

# make grep highlight results using color
export GREP_OPTIONS='--color=auto'

# Add some colour to LESS/MAN pages
export LESS_TERMCAP_mb=$'\E[01;31m'
export LESS_TERMCAP_md=$'\E[01;33m'
export LESS_TERMCAP_me=$'\E[0m'
export LESS_TERMCAP_se=$'\E[0m'
export LESS_TERMCAP_so=$'\E[01;42;30m'
export LESS_TERMCAP_ue=$'\E[0m'
export LESS_TERMCAP_us=$'\E[01;36m'

Cùng với việc điều chỉnh các tùy chọn khác nhau trong Bash, bạn cũng có thể sử dụng một số thủ thuật gọn gàng để tiết kiệm thời gian. Ví dụ:để chạy hai lệnh liên tục, bất kể trạng thái thoát của mỗi lệnh, hãy sử dụng ; để tách các lệnh, như bên dưới:

[user@centos /tmp]$ du -hsc * ; df -h

Điều này chỉ đơn giản là tính toán dung lượng mà mỗi tệp trong thư mục hiện tại chiếm (và tính tổng), sau đó nó truy vấn hệ thống về mức sử dụng đĩa trên mỗi thiết bị khối. Các lệnh này sẽ chạy bất kể lỗi nào được tạo bởi du lệnh.

Điều gì sẽ xảy ra nếu bạn muốn một hành động được thực hiện sau khi hoàn thành thành công lệnh đầu tiên? Bạn có thể sử dụng && viết tắt để chỉ ra rằng bạn chỉ muốn chạy lệnh thứ hai khi lệnh đầu tiên trả về trạng thái thoát thành công. Ví dụ:giả sử bạn chỉ muốn khởi động lại máy khi cập nhật thành công:

[root@arch ~]$ pacman -Syu --noconfirm && reboot

Đôi khi khi chạy một lệnh, bạn có thể muốn nắm bắt đầu ra của nó. Hầu hết mọi người đều biết về tee lệnh này sẽ sao chép đầu ra tiêu chuẩn sang cả thiết bị đầu cuối và tệp. Tuy nhiên, nếu bạn muốn nắm bắt đầu ra phức tạp hơn từ strace , bạn sẽ cần bắt đầu làm việc với chuyển hướng I / O. Chi tiết về chuyển hướng I / O nằm ngoài phạm vi của bài viết ngắn này, nhưng vì mục đích của chúng tôi, chúng tôi quan tâm đến STDOUTSTDERR . Cách tốt nhất để nắm bắt chính xác những gì bạn đang thấy là kết hợp cả hai trong một tệp. Để thực hiện việc này, hãy sử dụng 2>&1 chuyển hướng.

[root@arch ~]$ strace -p 1140 > strace_output.txt 2>&1

Thao tác này sẽ đưa tất cả đầu ra có liên quan vào một tệp có tên strace_output.txt để xem sau.

Đôi khi trong một lệnh chạy dài, bạn có thể cần phải tạm dừng việc thực hiện một tác vụ. Bạn có thể sử dụng phím tắt 'dừng' ctrl + z để dừng (nhưng không giết) một công việc. Công việc được thêm vào hàng đợi công việc, nhưng bạn sẽ không còn thấy công việc cho đến khi bạn tiếp tục. Công việc này có thể được tiếp tục sau đó bằng cách sử dụng lệnh nền trước fg .

Ngoài ra, bạn cũng có thể chỉ cần tạm dừng công việc bằng ctrl + s . Công việc và đầu ra của nó vẫn ở nền trước của thiết bị đầu cuối và việc sử dụng trình bao không không trả lại cho người dùng. Có thể tiếp tục công việc bằng cách nhấn ctrl + q .

Nếu bạn đang làm việc trong môi trường đồ họa với nhiều thiết bị đầu cuối đang mở, bạn có thể thấy tiện lợi khi có các phím tắt để sao chép và dán đầu ra. Để làm như vậy, hãy sử dụng các phím tắt sau:

# Copies highlighted text
ctrl + shift + c

# Pastes text in buffer
ctrl + shift + v

Giả sử trong đầu ra của một lệnh đang thực thi, bạn thấy một lệnh khác đang được thực hiện và bạn muốn lấy thêm thông tin. Có một số cách để làm điều này. Nếu lệnh này nằm trong đường dẫn của bạn ở đâu đó, bạn có thể chạy which để tìm ra vị trí của lệnh đó trên đĩa của bạn:

[root@arch ~]$ which ls
/usr/bin/ls

Với thông tin này, bạn có thể kiểm tra tệp nhị phân với tệp tab lệnh:

[root@arch ~]$ file /usr/bin/ls
/usr/bin/ls: ELF 64-bit LSB pie executable x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=d4e02b88e596e4f82c6cc62a5bc4ce5827209a49, stripped

Bạn có thể xem tất cả các loại thông tin, nhưng quan trọng nhất đối với hầu hết người dùng là ELF 64-bit LSB vô lý. Về cơ bản, điều này có nghĩa là nó là một tệp nhị phân được biên dịch trước trái ngược với một tập lệnh hoặc kiểu thực thi khác. Một công cụ liên quan mà bạn có thể sử dụng để kiểm tra các lệnh là lệnh tab công cụ của chính nó. Chỉ cần chạy lệnh command -V <command> sẽ cung cấp cho bạn các loại thông tin khác nhau:

[root@arch ~]$ command -V ls
ls is aliased to `ls --color=auto`

[root@arch ~]$ command -V bash
bash is /usr/bin/bash

[root@arch ~]$ command -V shopt
shopt is a shell builtin

Cuối cùng nhưng chắc chắn không kém phần quan trọng, một trong những thủ thuật yêu thích của tôi, đặc biệt là khi làm việc với vùng chứa hoặc trong môi trường mà tôi có ít kiến ​​thức hoặc khả năng kiểm soát, là echo yêu cầu. Lệnh này có thể được sử dụng để thực hiện mọi thứ, từ kiểm tra để đảm bảo rằng for vòng lặp sẽ chạy theo trình tự mong đợi để cho phép bạn kiểm tra xem các cổng từ xa có đang mở hay không. Cú pháp rất đơn giản để kiểm tra một cổng đang mở:echo > /dev/<udp or tcp>/<server ip>/<port> . Ví dụ:

user@ubuntu-1604:~$ echo > /dev/tcp/192.168.99.99/222
-bash: connect: Connection refused
-bash: /dev/tcp/192.168.99.99/222: Connection refused

user@ubuntu-1604:~$ echo > /dev/tcp/192.168.99.99/22

Nếu cổng bị đóng đối với loại kết nối bạn đang cố gắng thực hiện, bạn sẽ nhận được Connection refused thông điệp. Nếu gói được gửi thành công, sẽ không có đầu ra.

Tôi hy vọng những mẹo này sẽ làm cho Bash hiệu quả hơn và thú vị hơn khi sử dụng. Có nhiều thủ thuật ẩn trong Bash hơn tôi đã liệt kê ở đây. Một số mục yêu thích của bạn là gì?

Phụ lục 1. Danh sách các mẹo và thủ thuật được đề cập

# History related 
ctrl + r (reverse search)
!! (rerun last command)
!* (reuse arguments from previous command)
!$ (use last argument of last command)
shopt -s histappend (allow multiple terminals to write to the history file)
history | awk 'BEGIN {FS="[ \t]+|\\|"} {print $3}' | sort | uniq -c | sort -nr | head (list the most used history commands)

# File and navigation
cp /home/foo/realllylongname.cpp{,-old}
cd -
rename 's/text_to_find/been_renamed/' *.txt
export CDPATH='/var/log:~' (variable is used with the cd built-in.)

# Colourize bash

# enable colors
eval "`dircolors -b`"
# force ls to always use color and type indicators
alias ls='ls -hF --color=auto'
# make the dir command work kinda like in windows (long format)
alias dir='ls --color=auto --format=long'
# make grep highlight results using color
export GREP_OPTIONS='--color=auto'

export LESS_TERMCAP_mb=$'\E[01;31m'
export LESS_TERMCAP_md=$'\E[01;33m'
export LESS_TERMCAP_me=$'\E[0m'
export LESS_TERMCAP_se=$'\E[0m' # end the info box
export LESS_TERMCAP_so=$'\E[01;42;30m' # begin the info box
export LESS_TERMCAP_ue=$'\E[0m'
export LESS_TERMCAP_us=$'\E[01;36m'

# Bash shortcuts
    shopt -s cdspell (corrects typoos)
    ctrl + _ (undo)
    ctrl + arrow (move forward a word)
    ctrl + a (move cursor to start)
    ctrl + e (move cursor to end)
    ctrl + k (cuts everything after the cursor)
    ctrl + l (clears screen)
    ctrl + q (resume command that is in the foreground)
    ctrl + s (pause a long running command in the foreground)
    ctrl + t (swap two characters)
    ctrl + u (cuts everything before the cursor)
    ctrl + x + ctrl + e (opens the command string in an editor so that you can edit it before it runs)
    ctrl + x + * (expand glob/star)
    ctrl + xx (move to the opposite end of the line)
    ctrl + y (pastes from the buffer)
    ctrl + shift + c/v (copy/paste into terminal)

# Running commands in sequence
&& (run second command if the first is successful)
; (run second command regardless of success of first one)

# Redirecting I/O
2>&1 (redirect stdout and stderr to a file)

# check for open ports
echo > /dev/tcp/<server ip>/<port>
`` (use back ticks to shell out)

# Examine executable
which <command>
file <path/to/file>
command -V <some command binary> (tells you whether <some binary> is a built-in, binary or alias)