We collect practical, well-explained Bash one-liners, and promote best practices in Bash shell scripting. To get the latest Bash one-liners, follow @bashoneliners on Twitter. If you find any problems, report a bug on GitHub.

Tags

0

Blackhole ru zone

 $ echo "address=/ru/0.0.0.0" | sudo tee /etc/NetworkManager/dnsmasq.d/dnsmasq-ru-blackhole.conf && sudo systemctl restart network-manager

— by olshek_ on Nov. 14, 2017, 2:12 p.m.

Explanation

It creates dnsmasq-ru-blackhole.conf file with one line to route all domains of ru zone to 0.0.0.0.

You might use "address=/home.lab/127.0.0.1" to point allpossiblesubdomains.home.lab to your localhost or some other IP in a cloud.

0

Remove new lines from files and folders

 $ rename 's/[\r\n]//g' *

— by moverperfect on Sept. 30, 2017, 10:07 p.m.

Explanation

This will search all files and folders in the current directory for any with a new line character in them and remove the new line out of the file/folder.

1

Retrieve dropped connections from firewalld journaling

 $ sudo journalctl -b | grep -o "PROTO=.*" | sed -r 's/(PROTO|SPT|DPT|LEN)=//g' | awk '{print $1, $3}' | sort | uniq -c

— by FoxBuru on Sept. 14, 2017, 5:10 p.m.

Explanation

We take the output of journalctl since the last boot (-b flag) and output from PROTO= until the EOL. Then, we remove identification tags (PROTO=/SPT=/DPT=/LEN=) and print just the protocol and destination port (cols 1 and 3). We sort the output properly so we can aggregate them on the call over uniq.

Limitations

  • Only works on Linux
  • You use firewalld and you have logging set on ALL (see firewalld.conf for details)
  • You use journald for logging
  • Your user has sudo privileges

0

Kill a process running on port 8080

 $ lsof -i :8080 | awk 'NR > 1 {print $2}' | xargs --no-run-if-empty kill

— by Janos on Sept. 1, 2017, 8:31 p.m.

Explanation

lsof lists open files (ls-o-f, get it?). lsof -i :8080 lists open files on address ending in :8080. The output looks like this

COMMAND  PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
chrome  2619 qymspace  149u  IPv4  71595      0t0  TCP localhost:53878->localhost:http-alt (CLOSE_WAIT)`

We use awk 'NR > 1 {print $2}' to print the second column for lines except the first. The result is a list of PIDs, which we pipe to xargs kill to kill.

Limitations

The --no-run-if-empty option of xargs is available in GNU implementations, and typically not available in BSD implementations. Without this option, the one-liner will raise an error if there are no matches (no PIDs to kill).

0

Kill a process running on port 8080

 $ lsof -i :8080 | awk '{print $2}' | tail -n 1 | xargs kill

— by kimbethwel on Aug. 18, 2017, 8:22 a.m.

Explanation

lsof lists open files (ls-o-f, get it?). lsof -i :8080 lists open files on address ending in :8080. The output looks like this

COMMAND  PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
chrome  2619 qymspace  149u  IPv4  71595      0t0  TCP localhost:53878->localhost:http-alt (CLOSE_WAIT)`

We pipe this input through awk to print column 2 using the command awk '{print $2}' to produce the output:

PID
2533

To remote the word PID from this output we use tail -n 1 to grab the last row 2533,

We can now pass this process id to the kill command to kill it.

1

Get the latest Arch Linux news

 $ w3m https://www.archlinux.org/ | sed -n "/Latest News/,/Older News/p" | head -n -1

— by Jab2870 on Aug. 15, 2017, 10:35 a.m.

Explanation

w3m is a terminal web browser. We use it to go to https://www.archlinux.org/

We then use sed to capture the text between Latest News and Older News.

We then get rid of the last line which is Older News.

Limitations

For this, w3m would need to be installed. It should be installable on most systems.

If Arch change the format of there website significantly, this might stop working.

1

Make a new folder and cd into it.

 $ mkcd(){ NAME=$1; mkdir -p "$NAME"; cd "$NAME"; }

— by PrasannaNatarajan on Aug. 3, 2017, 6:49 a.m.

Explanation

Paste this function in the ~/.bashrc file.

Usage:

mkcd name1

This command will make a new folder called name1 and cd into the name1.

I find myself constantly using mkdir and going into the folder as the next step. It made sense for me to combine these steps into a single command.

1

Listen to the radio (radio2 in example)

 $ mpv http://a.files.bbci.co.uk/media/live/manifesto/audio/simulcast/hls/uk/sbr_med/llnw/bbc_radio_two.m3u8

— by Jab2870 on July 19, 2017, 2:44 p.m.

Explanation

MPV is a terminal audio player. You could also use vlc or any media player that supports streams.

To find a stream for your favourite uk radio station, look here: UK Audio Streams. If you are outside of the uk, Google is your friend

Limitations

Requires an audio player that supports streams.

1

Go up to a particular folder

 $ alias ph='cd ${PWD%/public_html*}/public_html'

— by Jab2870 on July 18, 2017, 6:07 p.m.

Explanation

I work on a lot of websites and often need to go up to the public_html folder.

This command creates an alias so that however many folders deep I am, I will be taken up to the correct folder.

alias ph='....': This creates a shortcut so that when command ph is typed, the part between the quotes is executed

cd ...: This changes directory to the directory specified

PWD: This is a global bash variable that contains the current directory

${...%/public_html*}: This removes /public_html and anything after it from the specified string

Finally, /public_html at the end is appended onto the string.

So, to sum up, when ph is run, we ask bash to change the directory to the current working directory with anything after public_html removed.

Examples

If I am in the directory ~/Sites/site1/public_html/test/blog/ I will be taken to ~/Sites/site1/public_html/

If I am in the directory ~/Sites/site2/public_html/test/sources/javascript/es6/ I will be taken to ~/Sites/site2/public_html/

1

Open another terminal at current location

 $ $TERMINAL & disown

— by Jab2870 on July 18, 2017, 3:04 p.m.

Explanation

Opens another terminal window at the current location.

Use Case

I often cd into a directory and decide it would be useful to open another terminal in the same folder, maybe for an editor or something. Previously, I would open the terminal and repeat the CD command.

I have aliased this command to open so I just type open and I get a new terminal already in my desired folder.

The & disown part of the command stops the new terminal from being dependant on the first meaning that you can still use the first and if you close the first, the second will remain open.

Limitations

It relied on you having the $TERMINAL global variable set. If you don't have this set you could easily change it to something like the following:

gnome-terminal & disown or konsole & disown

0

Preserve your fingers from cd ..; cd ..; cd..; cd..;

 $ up(){ DEEP=$1; for i in $(seq 1 ${DEEP:-"1"}); do cd ../; done; }

— by alireza6677 on June 28, 2017, 5:40 p.m.

Explanation

Include this function in your .bashrc

Now you are able to go back in your path simply with up N. So, for example:

Z:~$ cd /var/lib/apache2/fastcgi/dynamic/
Z:/var/lib/apache2/fastcgi/dynamic$ up 2
Z:/var/lib/apache2$ up 3
Z:/$

0

Get the HTTP status code of a URL

 $ curl -Lw '%{http_code}' -s -o /dev/null -I SOME_URL

— by Janos on June 19, 2017, 11:15 p.m.

Explanation

  • -w '%{http_code}' is to print out the status code (the meat of this post)
  • -s is to make curl silent (suppress download progress stats output)
  • -o /dev/null is to redirect all output to /dev/null
  • -I is to fetch the headers only, no need for the page content
  • -L is to follow redirects

0

Corporate random bullshit generator (cbsg)

 $ curl -s http://cbsg.sourceforge.net/cgi-bin/live | grep -Eo '^<li>.*</li>' | sed s,\</\\?li\>,,g | shuf -n 1 | cowsay

— by Jab2870 on June 7, 2017, 4:11 p.m.

Explanation

Lets make a cow talk BS

Limitations

I don't think cowsay is installed by default on a mac although it can be installed with brew cowsay

1

Generate a sequence of numbers

 $ perl -e 'print "$_\n" for (1..10);'

— by abhinickz6 on May 30, 2017, 2:47 p.m.

Explanation

Print the number with newline character which could be replaced by any char.

0

List the content of a GitHub repository without cloning it

 $ svn ls https://github.com/user/repo/trunk/some/path

— by Janos on May 21, 2017, 6:01 p.m.

Explanation

Git doesn't allow querying sub-directories of a repository. But GitHub repositories are also exposed as Subversion repositories, and Subversion allows arbitrary path queries using the ls command.

Notice the /trunk/ between the base URL of the repository and the path to query. This is due to the way GitHub provides Subversion using a standard Subversion repository layout, with trunk, branches and tags sub-directories.

1

Delete static and dynamic arp for /24 subnet

 $ for i in {1..254}; do arp -d 192.168.0.$i; done

— by dennyhalim.com on Oct. 21, 2016, 5:07 a.m.

Explanation

Simply loop from 1 to 254 and run arp -d for each IP address in the 192.168.0.0/24 network.

5

List status of all GIT repos

 $ find ~ -name ".git" 2> /dev/null | sed 's/\/.git/\//g' | awk '{print "-------------------------\n\033[1;32mGit Repo:\033[0m " $1; system("git --git-dir="$1".git --work-tree="$1" status")}'

— by uMt on Oct. 16, 2016, 11:19 p.m.

Explanation

  • List all .git dirs
  • Trim .git parts
  • Run git --git-dir=X.git --work-tree=X status with awk

1

Shuffle lines

 $ ... | perl -MList::Util=shuffle -e 'print shuffle <>;'

— by openiduser81 on Jan. 31, 2016, 9:02 p.m.

Explanation

Sorting lines is easy: everybody knows the sort command.

But what if you want to do the other way around? The above perl one-liner does just that:

  • -MList::Util=shuffle load the shuffle function from the List::Util package
  • -e '...' execute Perl command
  • print shuffle <> call List::Util::shuffle for the lines coming from standard input, read by <>

0

Create an array of CPU frequencies in GHz

 $ cpus=($({ echo scale=2; awk '/cpu MHz/ {print $4 " / 1000"}' /proc/cpuinfo; } | bc))

— by openiduser146 on Dec. 28, 2015, 9:02 p.m.

Explanation

  • The awk command takes the input from /proc/cpuinfo, matches lines containing "cpu MHz", and appends the " / 1000" to the CPU frequency, so it's ready for piping to bc
  • The echo scale=2 is for bc, to get floating point numbers with a precision of maximum two decimal points
  • Group the echo scale=2 and the awk for piping to bc, by enclosing the commands within { ...; }
  • Run the commands in a $(...) subshell
  • Wrap the subshell within (...) to store the output lines as an array

From the cpus array, you can extract the individual CPU values with:

cpu0=${cpus[0]}
cpu1=${cpus[1]}
cpu2=${cpus[2]}
cpu3=${cpus[3]}

If you don't need the values in GHz, but MHz is enough, then the command is a lot simpler:

cpus=($(awk '/cpu MHz/ {print $4}' /proc/cpuinfo))

Limitations

Arrays are Bash specific, might not work in older /bin/sh.

/proc/cpuinfo exists only in Linux.

0

Test git archive before actually creating an archive // fake dry run

 $ git archive master some/project/subdir | tar t

— by openiduser146 on Dec. 22, 2015, 2:29 p.m.

Explanation

git archive doesn't have a --dry-run flag, and it would be nice to see what files would be in the archive before actually creating it.

  • git archive master some/project/subdir
  • Create an archive from the master branch, with only a specified sub-directory of the project in it (instead of the entire repo)
  • Note: without specifying a file, the archive is dumped to standard output
  • tar t : the t flag of tar is to list the content of an archive. In this example the content comes from standard input (piped from the previous command)

In other words, this command creates an archive without ever saving it in a file, and uses tar t to list the contents. If the output looks good, then you can create the archive with:

git archive master -o file.tar some/project/subdir

1

Convert all flac files in dir to mp3 320kbps using ffmpeg

 $ for FILE in *.flac; do ffmpeg -i "$FILE" -b:a 320k "${FILE[@]/%flac/mp3}"; done;

— by Orkan on Sept. 20, 2015, 5:45 p.m.

Explanation

It loops through all files in current directory that have flac extension and converts them to mp3 files with bitrate of 320kpbs using ffmpeg and default codec.

1

Preserve your fingers from cd ..; cd ..; cd..; cd..;

 $ upup(){ DEEP=$1; [ -z "${DEEP}" ] && { DEEP=1; }; for i in $(seq 1 ${DEEP}); do cd ../; done; }

— by andreaganduglia on June 9, 2015, 3:09 p.m.

Explanation

Include this function in your .bashrc and on the following line alias up='upup'

Now you are able to go back in your path simply with up N. So, for example:

Z:~$ cd /var/lib/apache2/fastcgi/dynamic/
Z:/var/lib/apache2/fastcgi/dynamic$ up 2
Z:/var/lib/apache2$ up 3 
Z:/$

1

Get number of all Python Behave scenarios (including all examples from Scenario Outlines)

 $ behave -d | grep "scenarios passed" | cut -d, -f4 | sed -e 's/^[[:space:]]*//' | sed 's/untested/scenarios/g'

— by openiduser188 on April 17, 2015, 2:21 p.m.

Explanation

behave -d

-d stands for dry-run, so behave invokes formatters without executing the steps.

grep "scenarios passed"

Then we grep for the summary line containing number of all scenarios

cut -d, -f4

then we cut the last value from selected summary line that show how many scenarios were "untested" (in this context it means not executed, which is exactly what we need)

sed -e 's/^[[:space:]]*//'

Trim leading space

sed 's/untested/scenarios/g'

Lastly simple sed to replace untested with scenarios

2

Ban all IPs that attempted to access phpmyadmin on your site

 $ grep "phpmyadmin" $path_to_access.log | grep -Po "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" | sort | uniq | xargs -I% sudo iptables -A INPUT -s % -j DROP

— by openiduser187 on April 2, 2015, 8:58 a.m.

Explanation

Cheap security Bash one-liner to ban all IPs that are probably doing automated attacks.

Make sure your IP isn't listed before piping through iptables drop!!

  1. This will first find all lines in $path_to_access.log that have phpmyadmin in them,

  2. Then grep out the ip address from the start of the line,

  3. Then sort and unique them,

  4. Then add a rule to drop them in iptables

Again, just edit in echo % at the end instead of the iptables command to make sure your IP isn't in there. Don't inadvertently ban your access to the server!

Limitations

You may need to change the grep part of the command if you're on mac or any system that doesn't have grep -P.

-1

Get a free shell account on a community server

 $ sh <(curl hashbang.sh | gpg)

— by lrvick on March 15, 2015, 9:49 a.m.

Explanation

Bash process substitution which curls the website 'hashbang.sh' and executes the shell script embedded in the page.

This is obviously not the most secure way to run something like this, and we will scold you if you try.

The smarter way would be:

Download locally over SSL

curl https://hashbang.sh >> hashbang.sh

Verify integrity with GPG (if available):

gpg --recv-keys 0xD2C4C74D8FAA96F5
gpg --verify hashbang.sh

Inspect source code:

less hashbang.sh

Run:

chmod +x hashbang.sh
./hashbang.sh