shell

Run incognito/private commands for Bash and Zsh

Bash


Simply put a space before the command and it won't be saved to `~/.bash_history`. E.g. ` qrencode -o out.png "Some secret text"`

Zsh


Enable the following option to be able to run private commands by adding a space before and prevent it from being saved to `~/.zsh_history`.

setopt HIST_IGNORE_SPACE
5
Hicham

Upgrade postgres database with homebrew

To upgrade postgres you can run 

brew upgrade postgresql

After you've done that your existing databases will have data that is incompatible with the your new postgres binary. Normally you would have to use pg_update and pass in the correct binaries to migrate the data, however, brew includes an upgrade script to update the data for you.

brew postgresql-upgrade-database

9
Joe

Angry Docker Purge

If you receive No Space left error on Docker this the brute force solution:

It would stop and delete ALL containers, images and volumes.

docker stop $(docker ps -aq); docker rm $(docker ps -aq); docker volume rm $(docker volume ls -qf dangling=true);docker system prune -af


4
Babar

Run same command on different input/inputs

If you have to run the same command repetitively over different input/inputs.

Example input:

c595270372e3
c04094382ae1
498a6505a1f7
4ac0e1872789
170a7f2ec51a
930743cb4e19


Command:

pbpaste | xargs -I id docker image rm id


Note: pbpaste is clipboard paste command for Mac, would be different for operating systems.

1
Babar

Check for IKEA item availability

A bit of a hack, but we want to be notified if an item becomes available at IKEA.

This is just a shell script that should work on any *NIX that has curl installed.

This is how their API response looks like (replace th with your country code): https://www.ikea.com/th/en/iows/catalog/availability/S99067497

There are only two stores in Thailand, both of which are close enough to the Oozou office, we only care that it's available in one of those stores.

#!/usr/bin/env bash

url="https://www.ikea.com/th/en/iows/catalog/availability/$1"

# This is the string that we want to see changed
string="0"

while true; do
  # Get the API response and return as string
  text=$(curl -s "$url")

  # Get a count of how many times the substring matches
  count=`grep -o "$string" <<< "$text" | wc -l`

  # If less than 2, then it's available!
  if (( $count < 2 )); then
    echo "AVAILABLE, yay.";
    # Notify us via Slack
    curl -X POST --data-urlencode "payload={\"channel\": \"…\", \"username\": \"ikea\", \"text\": \"Item $1 is now available at IKEA.\", \"icon_emoji\": \":shooping_bags:\"}" https://hooks.slack.com/services/…
    break
  else
    # If not available, sleep for 30s
    echo "$1 not in stock"
    sleep 30
  fi
done



Pass in your item ID to start:

$ ./check.sh S99067497


5
Const

Go through a file Git history (GUI)

$ gitk --follow file


Ali

Kill unresponsive SSH session

Occasionally an SSH session may become unresponsive. If I put my laptop to sleep this happens fairly often. Rather than killing the tab you can use SSH Escape Characters to kill the session

$ ~.


To view all escape characters check man ssh and search for ESCAPE CHARACTERS $ /ESCAPE CHARACTERS

Joe

Kill rails that got stuck

I'd like to kill rails running w/specific port. (My laptop running several rails servers. )

kill -9 $(lsof -i :3000|grep ruby|head -1|awk '{print $2}')

Alyson

Using Git's aliases feature

Git allows you to create aliases internally through the config. Your global config should be located here ~/.gitconfig

[alias]
  aliases = !git config --get-regexp 'alias.*' | colrm 1 6 | sed 's/[ ]/ = /' | sort
  count = shortlog -sn
  l = log
  co = checkout
  ca = commit -C HEAD --amend
  c  = commit
  cm = commit -m
  a  = add
  s  = status
  b  = branch
  p  = push
  mt = mergetool
  dt = difftool
  o  = origin
  rc = rebase --continue
  rs = rebase --skip
  pd  = !git checkout develop && git pull origin develop && git branch --merged | grep -v '*' | grep -v 'master' | xargs git branch -d && git fetch --prune origin
  pm  = !git checkout master && git pull origin master && git branch --merged | grep -v '*' | grep -v 'develop' | xargs git branch -d && git fetch --prune origin
  pr = pull-request -c -m


Most are self explanatory...

git pd (prune develop) - checks out to develop, fetches latest changes, deletes all stale branches except develop (will delete master too)

git pm (prune master) - does the same as prune develop for master

Joe

See deleted files in previous commits [git]

$ git log --diff-filter=D --summary --oneline


Ali

Find a branch based on a commit

$ git log --oneline --all --grep=pretty

c198bb715 Make default expired description logic pretty


$ git branch --contains c198bb715

* deploy/staging
  feature/ROC-3042


2
Ali

Check if command exists with shell script

if ! type gem > /dev/null; then
  echo 'gem command not found.'
fi


Tino

Delete merged git branches

Handy git command for deleting all local git branches that already merged git branch --merged | egrep -v "(^\*|master|dev)" | xargs git branch -d

1
Stan

Watch CI status on Github

When you have Github's hub installed, you can get the ci-status of your current branch like this:

$ hub ci-status
pending


If you install watch (e.g. brew install watch) you can continuously see the state:

$ watch hub ci-status


Const

Bash aliases and magic

I have a seperate file in my user folder named ~/.aliases. I use this to store all of my bash aliases. I use aliases a lot and add new ones regularly so I created a bash function to add new aliases on the fly.

addalias() {
  echo 'alias '$1'="'$2'"' >> ~/.aliases
  source ~/.aliases
}


Now you can add an alias from the terminal which will be available to the current session and all new sessions... shell $ addalias foo 'echo "bar"'

If I find myself using commands over and over I will create aliases shell alias g='git' alias b='bundle' alias be='bundle exec' alias bu='bundle update' alias r='bin/rails' alias rr='bin/rails routes' alias migration='bin/rails generate migration' alias migrate='bin/rails db:migrate; bin/rails db:migrate RAILS_ENV=test' alias rollback="rake db:rollback; RAILS_ENV=test rake db:rollback" alias push='git push origin HEAD' alias pr='git pull-request -c -m' alias ppr="git push origin HEAD && git pull-request -m" alias pulls='git browse -- pulls' alias prs='git pr list' pull() { git browse -- pull/'$1' } alias la='ls -a' alias ll='ls -al'

3
Joe

Force push previous commit to repo

If you push some code and want to force push a previous commit you can do so with shell git push origin +commit_sha^:branch_name

Where git interprets sha^ as the parent of sha and + as a forced non-fastforward push.

You can also use HEAD^ where ^ is the parent of HEAD so HEAD^^^ would push the commit 3 commits before the current commit. e.g. shell git push origin +HEAD^^^:feature/i_did_an_oopsie

1
Joe

Get current git branch name

git rev-parse --abbrev-ref HEAD


Ali

Back up a file with same name + prefix

$ cp todo.txt !#:1.bak
cp todo.txt todo.txt.bak


NOTE: Actually you can use !#:1 in every command 'cause that's last argument passed to a command.

UPDATED: Now it works with zsh

239
Ali

Delete already-merged branchs in Git

$ git branch --merged | egrep -v 'master|develop' | xargs -n 1 git branch -d


You can safelist more branches in egrep -v 'master|develop|foo|bar'

1.07 Thousand
Ali

Diff a local file with remote version in Git

Easily run the below command and get a diff version from the remote

$ git diff origin/master -- [local-path]


1.07 Thousand
Ali

Remove unwanted commit from your branch

git rebase -p --onto SHA^ SHA


1.07 Thousand
Tino

Send messages to Slack using cURL

Slack allows you to send messages via the Webhooks service

Create a webhook for any channel and then you can send notification using curl.

$ curl -X POST -H 'Content-type: application/json' --data '{"text": "Something important"}'  https://hooks.slack.com/services/YOUR/TOKENIZED/URL

Setting Up Incoming Webhooks


Incoming webhooks are a simple way to post messages from apps into Slack. To set up an incoming webhook, you need to create a Slack app and enable incoming webhooks in the app settings. Here’s a step-by-step guide to setting up incoming webhooks:

  1. Log in to your Slack account and navigate to the Slack API main page.
  2. Click the “Create an app” button and select “From scratch.”
  3. Enter a name for your app and select the workspace where you want to deploy it.
  4. Click the “Create App” button.
  5. In the app settings, navigate to the “Features” section and click on “Incoming Webhooks.”
  6. Toggle the switch to enable incoming webhooks.
  7. Click the “Add New Webhook to Workspace” button.
  8. Select the channel where you want to post messages and click “Allow.”

By following these steps, you can create a Slack app and set up an incoming webhook to start sending messages to your chosen channel.

Creating a Payload


To send a message via an incoming webhook, you need to create a payload that contains the message text and some options. Here’s how to create a payload:

  1. Determine the content type of your payload. For incoming webhooks, the content type is always “application/json.”
  2. Create a JSON object that contains the message text and any additional options you want to include. For example:
    1. { "text": "Hello, Slack!", "username": "WebhookBot", "icon_emoji": ":ghost:" }
      
  3. Use a tool like curl to send the payload to the incoming webhook URL.
By creating a properly formatted JSON payload, you can ensure that your message is correctly sent to Slack via the incoming webhook.

Sending Messages with cURL


cURL is a command-line tool that you can use to send messages to Slack via an incoming webhook. Here’s an example of how to use cURL to send a message:

  1. Open a terminal and navigate to the directory where you want to send the message
  2. Create a file with a .json extension that contains the payload. For example, create a file named message.json with the following content:
    1. { "text": "Hello, World!" }
      
  3. Use the cURL command to send the payload to the incoming webhook URL: 
    1. curl -X POST -H 'Content-Type: application/json' --data @message.json https://hooks.slack.com/services/YOUR/TOKENIZED/URL
      
By following these steps, you can use cURL to send a message to Slack via an incoming webhook.

Testing and Troubleshooting


When testing and troubleshooting incoming webhooks, it’s essential to check the HTTP status code and response body for any errors. Here are some common errors you may encounter:

  • HTTP 400 Bad Request: The payload is malformed or missing required fields.
  • HTTP 403 Forbidden: The incoming webhook URL is invalid or no longer available.
  • HTTP 404 Not Found: The channel or workspace does not exist.

To troubleshoot issues, you can use tools like cURL to send test payloads and inspect the response. Additionally, you can check the Slack API documentation for more information on error codes and troubleshooting.

Advanced Slack Integration


Incoming webhooks are just one way to integrate with Slack. For more advanced integrations, you can use the Slack API to send and receive messages, create custom bots, and more. Here are some advanced Slack integration features:

  • Web API: The Slack Web API allows you to send and receive messages, create custom bots, and more.
  • Events API: The Slack Events API allows you to receive real-time updates on events such as messages, reactions, and more.
  • Botkit: Botkit is a framework for building custom bots on Slack.

By using these advanced features, you can create more sophisticated integrations with Slack and automate workflows, enhance user experience, and more.
24
Joe

List directory structure except one or more dirs

Ever wanted to display the structure of the current directory except or two directories?

#NPM or yarn project
tree -I node_modules


# Elixir Mix project
tree -I 'deps|test'


Ali

Use `host` to get more information about domains

You might be using dig to find out A/CNAME/MX etc records of a domain from DNS servers. But if you just want to get a quick overview, use host:

$ host oozou.com
oozou.com has address 52.89.55.136
oozou.com has address 35.165.206.160
oozou.com has address 34.212.209.65
oozou.com mail is handled by 1 aspmx.l.google.com.
oozou.com mail is handled by 5 alt1.aspmx.l.google.com.
oozou.com mail is handled by 5 alt2.aspmx.l.google.com.
oozou.com mail is handled by 10 aspmx2.googlemail.com.
oozou.com mail is handled by 10 aspmx3.googlemail.com.


2
Const

Zsh function to list file tree

When navigating through directories on the command line, it’s often helpful to see the structure of directories and subdirectories in a "tree" format. While there are plenty of tools out there, such as tree, sometimes you might want a simple custom solution integrated directly into your shell. In this post, we’ll walk through creating a simple Zsh function to list a directory’s structure in a tree format.

Creating a Zsh Function to List File Trees


If you're using Zsh as your default shell, adding a custom function to your .zshrc file can help you create a quick and efficient command for viewing directories in a tree structure. This function works similarly to the popular tree command but is built using ls and sed, making it easy to integrate directly into your Zsh environment.

Step 1: Add the lst() Function to .zshrc

The first step is to define the lst() function inside your .zshrc file. This function takes an optional argument, which can be any directory path, and lists the directory tree starting from that point. If no directory is specified, it defaults to the current directory.

Open your .zshrc file using your preferred text editor and add the following function:

lst() {
    if [ "$1" != "" ] # or better, if [ -n "$1" ]
    then
        ls -R $1 | grep ":$" | sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' -e 's/^/   /' -e 's/-/|/'
    else
        ls -R | grep ":$" | sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' -e 's/^/   /' -e 's/-/|/'
    fi
}


Step 2: Reload Your Zsh Configuration

After adding the function, you'll need to reload your .zshrc file for the changes to take effect. You can do this by running the following command in your terminal:

sh
source ~/.zshrc

Step 3: Using the lst() Function

Once you've added the function to your .zshrc, you can start using it right away. The lst() function allows you to list all the subdirectories in a specified directory in a tree format. Here’s how to use it:

To list the subdirectories of a folder (e.g., spec), run:
sh
lst spec

This command will generate a tree-like structure that lists all the subdirectories inside the spec folder.

If you want to see the tree structure of the current directory, simply run:
sh
lst

The lst() function will output the folder structure, making it easier to understand the hierarchy of your directories.

Example Output

Let’s say you have the following directory structure:

bash
spec/
├── controllers/
│   └── users/
├── models/
└── views/
Running the command lst spec would produce output similar to the following:

css
   spec
   |--controllers
   |   |--users
   |--models
   |--views
This simple tree structure makes it easy to visualize the relationships between directories and subdirectories.

How It Works

Let’s break down the function step-by-step:

  1. ls -R $1: The ls -R command recursively lists the contents of the directory (or current directory if no argument is provided).
  2. grep ":$": Filters the results to only show directory names (lines ending with :).
  3. sed Commands:
    • 's/:$//': Removes the colon at the end of each directory name.
    • 's/[^-][^\/]*\//--/g': Replaces forward slashes (/) with dashes (--), converting the structure into a tree-like format.
    • 's/^/ /': Adds indentation to the directory tree.
    • 's/-/|/': Replaces dashes with vertical pipes (|), further enhancing the tree format.

Step 4: Customize the lst() Function

You can easily customize the lst() function to suit your needs. For example, you can change the formatting of the tree structure or add additional options for listing files. If you frequently need to list files as well as directories, you could modify the function to include files by removing the grep filter that only shows directories.

Alternative: Using the tree Command

If you prefer, you can use the tree command, which is designed specifically for displaying directory structures. tree is a widely available utility and can be installed on most Unix-like systems. To install tree, use one of the following commands depending on your system:

On Ubuntu or Debian-based systems:
sh
sudo apt-get install tree

On macOS:
sh
brew install tree

Once installed, you can use the tree command to generate similar output:
sh
tree spec

The tree command provides more features out of the box, such as the ability to display file sizes, permissions, and more. However, if you prefer to keep things simple or if tree is not available, the lst() function is a great lightweight alternative.

Conclusion

The Zsh function we’ve created provides a simple and efficient way to list directory structures in a tree format. By adding the lst() function to your .zshrc file, you can quickly visualize the subdirectories of any folder on your system. This can be incredibly useful for navigating complex directory structures and understanding the hierarchy of files and folders in your projects.

If you're looking for more functionality, consider using the tree command for more advanced features. However, for lightweight, custom solutions integrated directly into your Zsh shell, the lst() function is a perfect choice.

FAQs


1. What is the lst() function used for?

The lst() function is a custom Zsh function that displays the directory structure in a tree format. It uses ls and sed to format the output, making it easy to visualize folder hierarchies directly in the terminal.

2. How do I add the lst() function to my Zsh configuration?

You can add the lst() function by editing your .zshrc file and pasting the function definition into the file. After that, run source ~/.zshrc to reload the configuration and make the function available.

3. Can I customize the output of the lst() function?

Yes, you can customize the function by modifying the sed commands that format the output. You can change the tree structure, add more details, or even include files in the listing.

4. What is the alternative to using the lst() function?

The tree command is a widely available utility that displays directory structures in a tree format. It offers more features than the lst() function and can be installed on most Unix-like systems.

5. Can I use the lst() function on systems other than Zsh?

The lst() function is written for Zsh, but it can be easily adapted for other shells like Bash by adding it to the appropriate configuration file (.bashrc for Bash).

By integrating the lst() function into your Zsh workflow, you can enhance your command-line experience and make directory navigation much easier.

Tino

Create your own git commands (aliases)

Ever wanted to shorten a git command? You can go with shell alilas for sure but you have to always include context so that you don't forget what each ailas stands for but you can define your own commands in git using aliases.

git config --global alias.  


For example; I'm too lazy to type git status so I want to shorten this to git s

git config --global alias.s status


And here we go now you can just type git s and get the status of current repository.

Ali

Amazon AWS S3 CLI copy with set perms

Open term (or equivalent) and paste the following:

S3 copy

  • to upload a world-readable file:
aws s3 cp source.file s3://bucket/path/dest.file --acl public-read


Options for --acl parameters are:

  • private - visibility to owner only
  • public-read - readable by all
  • public-read-write - readable and writable by all
Jeff

Restore a deleted file in Git

# Find in which commit it's been deleted
$ git rev-list -n 1 HEAD -- 
4058ef780d2f6c4c6d57cfd7fd4ebe14c9dc28b3
# Restore it back
$ git checkout 4058ef780d2f6c4c6d57cfd7fd4ebe14c9dc28b3^ -- 


1.07 Thousand
Ali

make a pr from command line using hub

install hub first with brew: brew install hub then use a simple command, like at the example below: hub pull-request -m "best pr ever" -b oozou:develop -h feature/awesome-improvements

or even smarter:

hub pull-request -m "best pr ever" -b oozou:develop -h $(git rev-parse --abbrev-ref HEAD)


for more detailed info how to make pull requests see at hub pull-request --help

1.07 Thousand
Stan

Shallow clone a old repo

If you don't need the full git history for a repo you will be working on you can supply a clone depth to only clone x revisions of the repo.

git clone --depth=1 https://github.com/my/repo.git

829
Joe