A Bash scripting question

So, I found a video talking about a neat little thing you can do to get better ‘examples’ for command line commands…

Cheat.sh

The concept was, if you wanted some examples of grep that were easier examples than diving through a man page, you could use curl and at the command line, type curl https://cheat.sh/grep and in the blink of an eye, you would get

# grep
# Matches patterns in input text.
# Supports simple patterns and regular expressions.

# Search for an exact string:
grep search_string path/to/file

# Search in case-insensitive mode:
grep -i search_string path/to/file

# Search recursively (ignoring non-text files) in current directory for an exact string:
grep -RI search_string .

# Use extended regular expressions (supporting `?`, `+`, `{}`, `()` and `|`):
grep -E ^regex$ path/to/file

# Print 3 lines of [C]ontext around, [B]efore, or [A]fter each match:
grep -C|B|A 3 search_string path/to/file

# Print file name with the corresponding line number for each match:
grep -Hn search_string path/to/file

# Use the standard input instead of a file:
cat path/to/file | grep search_string

# Invert match for excluding specific strings:
grep -v search_string

which is very useful!!

So, what I wanted to do was create an alias so I could just type cheat grep and get the same results…

However, that won’t work because of the space (it would send curl https://cheat.sh/ grep) which results in the cheat.sh main page and then curl: (6) Could not resolve host: grep because of the space…

So I tried to make a bash function…

function cheat { curl https://cheat.sh/$1 }

which gives me the same error…

So how can I create a function/alias for this to work… and if it’s a bash function, where should I put it (it’s own file or a custom ‘bash scripts’ file that has more than this), and where can I link it so that it always runs when I type cheat from the command line (I was originally thinking bash rc - but then just like it’s better to put custom aliases in their own file, I figured I should put custom small functions in their own file as well)

Sorry for rambling!

3 Likes

You don’t need to make it a function, this worked for me on Debian.

Create a file named “cheat” and make it executable containing:

#!/bin/sh
curl https://cheat.sh/$1

sudo mv ./cheat /usr/bin/cheat
cheat grep

2 Likes

Also this is very cool. Thank you.

2 Likes

Unfortunately this does not work for me with Ubuntu Mate (20.04)… I have to sudo to put it into /usr/bin and then when I run cheat it says permission denied, and if I run sudo cheat, it says it can’t find the command.

Put it in a $PATH location that is accessible to your user.

Use $echo $PATH to see which dirs are in it.

This is a really cool idea! It presents the output a little better for me if piped through less.

1 Like

I hopped in an Ubuntu VM and $echo $PATH outputted:

bash: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin: No such file or directory

Which has /usr/bin in it interestingly.

Here’s another option:

sudo mv ./cheat /opt/cheat

…and for anyone new seeing this you need to install curl:

sudo apt install curl

More stuff about cheat.sh on TWinL if anyone’s interested:

2 Likes

Wasn’t thinking about needing to install curl - since it’s part of my install script…

I just went the easy route and added the cheat function in the bottom of .bashrc

function cheat {
    /usr/bin/curl https://cheat.sh/$1
}

but thanks for your hlep @Ulfnic it was appreciated!

While we are at it, here is one for you @Ulfnic

I remember one of the command line tips/tricks from DL was !! which was to repeat the last command… so if your forgot, for example, the sudo command, on say apt update you could do sudo !! and it would be the same as running sudo apt update

An example that they gave an alias for it…
alias please='sudo !!'

So I put that command in my bash_aliases file, and when I run it, I get
sudo: !!: command not found

I’m not sure why this doesn’t work for me… because if I manually type sudo !! after running apt update it works as expected…

2 Likes

I have also seen ! followed by another character to represent the last command used that started with that letter. It is a good shortcut.

df -h
echo 'meow'
!d

The problem is you’re using quotes so the it’s trying to run 'sudo !!' instead of sudo !!

Just do: alias please=sudo !!

I like the humor with the please :stuck_out_tongue:

Well - when I take the ticks off and try just alias please=sudo !!, when I open my terminal - I get the error
bash: alias: !!: not found

And, for the record, all of my aliases have ticks around them - and they all work except this one…

Something like this should work even if the command has standard input, output redirection:

alias please=‘sudo “$BASH” -c “$(history -p !!)”’

It seems that Bash has to expand !! directly and it is not done through alias substitution. Section 9.3 of the below website has a more in depth treatment of History Expansion if you are interested:

Bash Reference Manual

3 Likes

Learning moment… the reason I thought it was the quotes is because I tried it right after using my test command. Without the quotes the interpreter runs everything beyond the “=” so sudo !! dragged my test command into the assignment prior to it being assigned. The interpreted version even shows up in the terminal history instead of the one I wrote. That meant whenever I ran the alias it outputted my test rather than a sudo of the previous command making me think it worked.

Thanks for the answer @charlesDelaware!

1

1 Like

Ah ha! That makes sense. Glad I could help :slight_smile:

2 Likes

This works. Add this to wherever you store your aliases:

function cheatsheet
{
curl cheat.sh/$1
}
alias cheat=“cheatsheet”