{"id":22331092,"url":"https://github.com/rodrigobdz/linux-cheatsheet","last_synced_at":"2026-02-17T11:31:26.845Z","repository":{"id":119408268,"uuid":"326202951","full_name":"rodrigobdz/linux-cheatsheet","owner":"rodrigobdz","description":"Collection of useful Linux commands","archived":false,"fork":false,"pushed_at":"2022-05-28T14:56:08.000Z","size":71,"stargazers_count":9,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-09T03:42:21.894Z","etag":null,"topics":["centos","certification-prep","command-line","debian","disk-space","docker","docker-compose","filesystem","linux","peripherals","ubuntu","usb-devices"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rodrigobdz.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-01-02T14:44:00.000Z","updated_at":"2025-07-25T23:25:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"77bff7a1-c33d-4b0d-b895-85312a31368a","html_url":"https://github.com/rodrigobdz/linux-cheatsheet","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rodrigobdz/linux-cheatsheet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rodrigobdz%2Flinux-cheatsheet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rodrigobdz%2Flinux-cheatsheet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rodrigobdz%2Flinux-cheatsheet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rodrigobdz%2Flinux-cheatsheet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rodrigobdz","download_url":"https://codeload.github.com/rodrigobdz/linux-cheatsheet/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rodrigobdz%2Flinux-cheatsheet/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29542522,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-17T08:11:05.436Z","status":"ssl_error","status_checked_at":"2026-02-17T08:09:38.860Z","response_time":100,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["centos","certification-prep","command-line","debian","disk-space","docker","docker-compose","filesystem","linux","peripherals","ubuntu","usb-devices"],"created_at":"2024-12-04T04:09:39.324Z","updated_at":"2026-02-17T11:31:26.825Z","avatar_url":"https://github.com/rodrigobdz.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Linux Cheatsheet\n\n**Highly recommended:** [tldr-pages/tldr](https://github.com/tldr-pages/tldr) ([website](https://tldr.sh))\n\n\u003e collection of community-maintained help pages for command-line tools, that aims to be a simpler, more approachable\n\u003e complement to traditional man pages.\n\n---\n\n- [Linux Cheatsheet](#linux-cheatsheet)\n  - [OS-specific](#os-specific)\n    - [CentOS](#centos)\n    - [Ubuntu](#ubuntu)\n  - [System-wide configuration](#system-wide-configuration)\n    - [System Services](#system-services)\n    - [Logs](#logs)\n    - [Networking](#networking)\n      - [SSH](#ssh)\n    - [Env vars](#env-vars)\n    - [Filesystem](#filesystem)\n    - [Peripherals](#peripherals)\n      - [Further Reading](#further-reading)\n    - [Default editor](#default-editor)\n    - [Disk Space](#disk-space)\n    - [RAM](#ram)\n    - [Swap Memory](#swap-memory)\n  - [User-specific configuration](#user-specific-configuration)\n  - [Git](#git)\n  - [GPG](#gpg)\n  - [Docker](#docker)\n    - [Docker in Docker (DinD)](#docker-in-docker-dind)\n    - [Update a Docker image](#update-a-docker-image)\n  - [Image Manipulation](#image-manipulation)\n  - [PDF manipulation](#pdf-manipulation)\n  - [Optimization](#optimization)\n    - [Parallel](#parallel)\n    - [Time](#time)\n    - [Copy dirs and files](#copy-dirs-and-files)\n  - [String manipulation](#string-manipulation)\n  - [Shell Scripting](#shell-scripting)\n  - [Related Projects](#related-projects)\n\n## OS-specific\n\n### CentOS\n\n- [Yum Command Cheat\n  Sheet](https://access.redhat.com/sites/default/files/attachments/rh_yum_cheatsheet_1214_jcs_print-1.pdf)\n\n### Ubuntu\n\n- Unattended reboot\n\n  ```sh\n  sudo editor /etc/gdm3/custom.conf\n\n  # Uncomment the following lines and change user1 to the value of $USER:\n  #   AutomaticLoginEnable = true\n  #   AutomaticLogin = user1\n  ```\n\n- [Debian Unattended Upgrades](https://wiki.debian.org/UnattendedUpgrades)\n- Reinstall Unity on Ubuntu\n\n  ```sh\n  sudo apt-get update\n  sudo apt-get install --reinstall ubuntu-desktop\n  sudo apt-get install --reinstall unity\n  ```\n\n- Fix `mesg: ttyname failed: Inappropriate ioctl for device`\n\n  Comment out `mesg n || true` in `/root/.profile`:\n\n  ```sh\n  # mesg n || true\n  test -t 0 \u0026\u0026 mesg n\n  ```\n\n  [Source](https://superuser.com/a/1277604)\n\n## System-wide configuration\n\n### System Services\n\n- Print service definition\n\n  ```sh\n  systemctl cat SERVICE_NAME.service\n  ```\n\n### Logs\n\n- Recover logs from failed `/etc/fstab` during boot\n\n  - Search by **date**\n\n    ```sh\n    journalctl --since today\n    ```\n\n  - Search by **keyword**\n\n    ```sh\n    grep --ignore-case --regexp=KEYWORD --files-with-matches --dereference-recursive /var/log 2\u003e /dev/null\n    ```\n\n  - Search by **file**\n\n    ```sh\n    journalctl --file /var/log/FILENAME.journal\n    ```\n\n### Networking\n\n- Connect to network on interface `eth0` on boot\n\n  ```sh\n  sudo systemctl status network\n  sudo editor /etc/sysconfig/network-scripts/ifcfg-eth0\n  # Set ONBOOT=yes for desired network\n  ```\n\n- Set DNS server\n\n  ```sh\n  editor /etc/resolv.conf\n  # Add DNS server\n  #   Example:\n  #     nameserver 8.8.8.8\n  ```\n\n  [Source](https://developers.google.com/speed/public-dns/docs/using)\n\n- List kernel routing tables\n\n  ```sh\n  route --numeric\n  ```\n\n#### SSH\n\n- Generate SSH key\n\n  ```sh\n  # -t specifies the type of key to generate\n  # -C provides a comment for the key\n  ssh-keygen -t ed25519 -C \"your_email@example.com\"\n  ```\n\n  [Source](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)\n\n- Test passphrase for SSH key\n\n  ```sh\n  # -y \"This option will read a private OpenSSH format file and print an OpenSSH public key to stdout.\"\n  ssh-keygen -y -f \u003cyour_private_ssh_key\u003e\n  ```\n\n- Regenerate remote host identification entry in `known_hosts` file\n\n  ```sh\n  ssh-keygen -f \"~/.ssh/known_hosts\" -R \u003cIP_ADDRESS\u003e\n  ```\n\n- [SSH Message Numbers](https://www.iana.org/assignments/ssh-parameters/ssh-parameters.xhtml#ssh-parameters-1)\n\n  Examples:\n\n  \u003e send packet: type 50 receive packet: type 51\n\n### Env vars\n\n- Given a file named `example.env` with contents:\n\n  ```sh\n  a='jane'\n  b='john'\n  c='doe'\n  ```\n\n  - Source all variables:\n\n    ```sh\n    source example.env\n    ```\n\n  - Export all variables in file\n\n    ```sh\n    # After sourcing all variables, we can export them\n    export $(cut --delimiter= --fields=1 example.env)\n    ```\n\n    [Source](https://unix.stackexchange.com/a/79065)\n\n### Filesystem\n\n- Filesystem Hierarchy Standard (FHS)\n\n  \u003e The Filesystem Hierarchy Standard (FHS) defines the directory structure and directory contents in Linux\n  \u003e distributions. [Source](https://en.m.wikipedia.org/wiki/Filesystem_Hierarchy_Standard)\n\n---\n\n- List 5 largest files in folder and sort by size\n\n  ```sh\n  du --human-readable --summarize * | sort --reverse --human-numeric-sort | head --lines 5\n  ```\n\n- Report file system disk space usage\n\n  ```sh\n  df --human-readable\n  ```\n\n- Create filesystem on external disk\n\n  ```sh\n  # Create filesystem\n  mkfs.ext4 /dev/vdb\n\n  # Create mountpoint directory\n  mkdir --parents /data\n\n  # Mount external disk to /data\n  mount /dev/vdb /data\n  ```\n\n- Mount from `/etc/fstab`\n\n  ```sh\n  mount --all\n  ```\n\n- List all partitions and their Universally Unique Identifier (UUID)\n\n  ```sh\n  sudo blkid\n  ```\n\n- Create sequence of numbered directories\n\n  ```sh\n  # Creates directories 1/ ... 10/\n  mkdir -p $(seq 1 10)\n  ```\n\n### Peripherals\n\n- Cheatsheet from `opensource.com`: [Linux commands to display your hardware\n  information](https://opensource.com/article/19/9/linux-commands-hardware-information)\n\nAs a general rule device shown in `/dev/sd*` are storage devices as opposed to the ones shown in `/dev/bus`.\n\n- List connected system devices\n\n  ```sh\n  find /dev/sd*\n  ```\n\n- List available USB ports\n\n  - Simple\n\n    ```sh\n    find /dev/bus/\n    ```\n\n  - Advanced\n\n    ```sh\n    ls /sys/bus/usb/devices/*\n    ```\n\n- Display info for specific USB device\n\n  ```sh\n  sudo lsusb -D /dev/bus/usb/001/005\n  ```\n\n- List block devices\n\n  ```sh\n  lsblk\n  ```\n\n- List the partition tables for the specified devices\n\n  ```sh\n  sudo fdisk --list\n  ```\n\n- List hardware\n\n  ```sh\n  sudo lshw\n  ```\n\n- List hardware (only input devices)\n\n  ```sh\n  sudo lshw -class disk -class input -short\n  ```\n\n- List USB devices\n\n  - `usb-devices`\n\n    \u003e usb-devices is a (bash) shell script that can be used to display details of USB buses in the system and the\n    \u003e devices connected to them.\n\n    ```sh\n    usb-devices\n    ```\n\n    [Source](https://linux.die.net/man/1/usb-devices)\n\n  - `lsusb`\n\n    \u003e lsusb is a utility for displaying information about USB buses in the system and the devices connected to them\n\n    ```sh\n    lsusb\n    ```\n\n    [Source](https://linux.die.net/man/1/usb-devices)\n\n  - `usbview`\n\n    \u003e usbview provides a **graphical** summary of USB devices connected to the system. Detailed information may be\n    \u003e displayed by selecting individual devices in the tree display.\n\n    ```sh\n    usbview\n    ```\n\n    [Source](https://linux.die.net/man/1/usb-devices)\n\n#### Further Reading\n\n- [Interpreting the output of lsusb](https://diego.assencio.com/?index=1363692dafeabeff8e3f975077f92dfe)\n- [Find USB device details in Linux/Unix using LSUSB\n  command](https://www.linuxnix.com/find-usb-device-details-in-linuxunix-using-lsusb-command/)\n- [USB Descriptors](https://www.beyondlogic.org/usbnutshell/usb5.shtml)\n\n### Default editor\n\n- Set default editor for `sudo systemctl edit --full SERVICE_NAME`\n\n  ```sh\n  sudo update-alternatives --config editor\n  ```\n\n### Disk Space\n\n- Check available disk space\n\n  ```sh\n  df --human-readable / | awk 'END{print $4}' | cut --delimiter='G' --fields=1\n  ```\n\n### RAM\n\n- Check available RAM\n\n  ```sh\n  free --total --gibi | awk '/Total:/ { print $2 }'\n  ```\n\n### Swap Memory\n\n- Configure swap memory (run as `root` user)\n\n  ```sh\n  configure_swap_memory() {\n    local -r swap_file_path=\"$1\"\n    local -r swap_memory_size_in_gb=\"$2\"\n\n    set -o errexit\n    set -o pipefail\n    set -o nounset\n\n    echo 'Disable all swap memory temporarily'\n    swapoff --all\n\n    # ATTENTION: fallocate is faster than dd but some systems require dd usage.\n    # If the fallocate command below fails, use the following instead:\n    #\n    # size=$((swap_memory_size_in_gb * 1024))\n    # sudo dd if=/dev/zero of=\"$swap_file_path\" count=$size bs=1MiB\n    #\n    echo \"Create $swap_file_path of size ${swap_memory_size_in_gb}GB\"\n    fallocate --length \"${swap_memory_size_in_gb}G\" \"$swap_file_path\"\n\n    echo \"Set up a Linux swap area in file $swap_file_path\"\n    mkswap \"$swap_file_path\"\n\n    echo \"Enable file $swap_file_path for paging and swapping\"\n    swapon \"$swap_file_path\"\n\n    echo \"Setting file permissions to 0600 of $swap_file_path\"\n    chmod 600 \"$swap_file_path\"\n\n    echo 'Verify increased size of swap memory'\n    grep SwapTotal /proc/meminfo\n  }\n\n  configure_swap_memory '/swapfile' 8\n  ```\n\n- [Recommended size of swap space](https://opensource.com/article/18/9/swap-space-linux-systems)\n\n## User-specific configuration\n\n- Set locale\n\n  Follow the instructions below to fix the following warnings:\n\n  \u003e perl: warning: Setting locale failed.\n  \u003e\n  \u003e perl: warning: Please check that your locale settings:\n  \u003e\n  \u003e LANGUAGE = (unset),\n  \u003e\n  \u003e LC_ALL = (unset),\n  \u003e\n  \u003e LC_CTYPE = \"UTF-8\",\n  \u003e\n  \u003e LANG = \"en_US.UTF-8\"\n  \u003e\n  \u003e are supported and installed on your system.\n  \u003e\n  \u003e perl: warning: Falling back to the standard locale (\"C\").\n\n  Append the following lines to `~/.bashrc`:\n\n  ```sh\n  export LANGUAGE=en_US.UTF-8\n  export LC_ALL=en_US.UTF-8\n  export LANG=en_US.UTF-8\n  export LC_CTYPE=en_US.UTF-8\n  ```\n\n- Preserve env when executing `sudo`\n\n  ```sh\n  sudo --preserve-env \u003ccommand\u003e\n  ```\n\n- Print non-root username\n\n  ```sh\n  # Returns name of user with UID 1000 (defaults to non-root user)\n  uid=1000\n  getent passwd \"$uid\" | cut -d: -f1\n  ```\n\n  [Source](https://unix.stackexchange.com/a/36582)\n\n  Alternatively:\n\n  ```sh\n  # \"SUDO_USER Set to the login name of the user who invoked sudo.\"\n  echo $SUDO_USER\n  ```\n\n  [Source](https://man7.org/linux/man-pages/man8/sudo.8.html)\n\n## Git\n\n- Mark all subdirectories as safe in git\n\n  ```sh\n  # ls options\n  # -1 list one file per line\n  #\n  # xargs options\n  # -L max. lines\n  \\ls -1 --directory $PWD/. | xargs -L 1 --delimiter='\\n' git config --global --add safe.directory\n  ```\n\n- Delete local and remote tag\n\n  ```sh\n  # Delete local tag\n  git tag --delete \u003cTAG_NAME\u003e\n  # Delete remote tag\n  git push --delete origin \u003cTAG_NAME\u003e\n  ```\n\n- Rename local and remote branch\n\n  ```sh\n  # Placeholders: old_name new_name\n\n  # If old_name not checked out already\n  git checkout old_name\n\n  # Rename local branch\n  git branch -m old_name new_name\n\n  # Delete old_name remote branch and push new_name local branch\n  git push origin :old_name new_name\n\n  # Reset upstream branch fo new_name local branch\n  git push origin --set-upstream new_name\n  ```\n\n  [Source](https://stackoverflow.com/questions/30590083/how-do-i-rename-both-a-git-local-and-remote-branch-name/45561865#45561865)\n\n- List changed files on branch with regard to main branch\n\n  ```sh\n  git --no-pager diff --name-only FETCH_HEAD $(git merge-base FETCH_HEAD main)\n  ```\n\n  [Source](https://stackoverflow.com/questions/25071579/list-all-files-changed-in-a-pull-request-in-git-github/25071749#25071749)\n\n- Improve performance of `git clone`\n\n  Read GitHub's [performance\n  comparison](https://github.blog/2020-12-22-git-clone-a-data-driven-study-on-cloning-behaviors/) for `git clone` and\n  [introduction to shallow and partial\n  clone](https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/#:~:text=git%20clone%20%2D%2Dfilter%3Dtree,need%20access%20to%20commit%20history.)\n\n- Solve merge conflict\n\n  ```sh\n  git mergetool\n  ```\n\n- Check performance metrics and recommendations for git repo using [git-sizer](https://github.com/github/git-sizer)\n\n  ```sh\n  git-sizer --verbose\n  ```\n\n- List biggest files in `.git` folder\n\n  ```sh\n  git rev-list --objects --all \\\n  | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \\\n  | sed --quiet 's/^blob //p' \\\n  | sort --numeric-sort --key=2 \\\n  | tail --lines 10 \\\n  | cut --characters=1-12,41- \\\n  | $(command -v gnumfmt || echo numfmt) --field=2 --to=iec-i --suffix=B --padding=7 --round=nearest\n  ```\n\n  [Source](https://stackoverflow.com/questions/9456550/how-to-find-the-n-largest-files-in-a-git-repository/46085465#46085465)\n\n- Git pull all repos in a directory\n\n  ```sh\n  find . -type d -depth 1 -exec git --git-dir={}/.git --work-tree=$PWD/{} pull \\;\n  ```\n\n  [Source](https://stackoverflow.com/a/12495234/2227405)\n\n## GPG\n\n- List all keys in long-format\n\n  ```sh\n  gpg --list-secret-keys --keyid-format LONG\n  ```\n\n- Generate a new GPG key pair\n\n  ```sh\n  gpg --full-generate-key\n  # Follow instructions from link below\n  ```\n\n  [Source](https://docs.github.com/en/github/authenticating-to-github/generating-a-new-gpg-key)\n\n- Delete GPG key pair\n\n  ```sh\n  # Delete secret key\n  gpg --delete-secret-key \u003ckey-ID\u003e\n  # Delete public key\n  gpg --delete-key \u003ckey-ID\u003e\n  ```\n\n- Renew expired yarn GPG key\n\n  ```sh\n  curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -\n  ```\n\n  [Source](https://github.com/yarnpkg/yarn/issues/7866#issue-558663837)\n\n## Docker\n\n- Watch status of Docker containers\n\n  You may need to install the `watch` command depending on your Linux distribution.\n\n  ```sh\n  # Interval unit is seconds\n  watch --interval 1 'docker ps -a'\n  ```\n\n- Enter a crashing Docker container\n\n  ```sh\n  docker commit \u003ccontainer_id\u003e my-broken-container\n  docker run --interactive --tty my-broken-container /bin/bash\n  ```\n\n- Check cause of container crash\n\n  ```sh\n  dmesg --ctime | grep --extended-regexp --ignore-case --before-context=100 'killed process'\n  ```\n\n- Find absolute path to Docker volume in file system\n\n  ```sh\n  docker volume inspect --format '{{ .Mountpoint }}' VOLUME_NAME\n  ```\n\n- Search local Docker images by name\n\n  ```sh\n  # Replace placeholder IMAGENAME by Docker image name you are searching for\n  docker images '*IMAGENAME*'\n  ```\n\n### Docker in Docker (DinD)\n\nThe trick is to mount `/var/run/docker.sock` as a volume. The Docker container can then access Docker on the host.\n\n[Source](https://itnext.io/docker-in-docker-521958d34efd)\n\n### Update a Docker image\n\nThe following image uses the image `my_image:my_tag` as a placeholder.\n\n```sh\n# Replace placeholder image_name with the name of the image you want to update\nimage_name=my_image:my_tag\ncontainer_name=update-image-container\n\n# Start a container with the image to update\ndocker run --rm --tty --detach --name \"$container_name\" \"$image_name\"\n\n# Log into the image to update it\ndocker exec --interactive --tty \"$container_name\" bash\n# Update the image (the following command is executed inside the image). Example:\ntouch /tmp/new_file.txt\n# Exit the image\nexit\n\n# Commit the image, i.e., create a new image from the container’s changes\ndocker commit \"$container_name\" \"$image_name\"\n\ndocker stop \"$container_name\"\n```\n\n## Image Manipulation\n\n[Source](https://tldr.ostera.io/convert)\n\n- Horizontally append images\n\n  ```sh\n    convert *.png +append horizontal-image.png\n  ```\n\n- Vertically append images\n\n  ```sh\n    convert *.png -append vertical-image.png\n  ```\n\n- Create image with white background\n\n  ```sh\n  convert -size 32x32 xc:white empty.jpg\n  ```\n\n- Replace alpha channel with white background in all PNG images in nested directories\n\n  ```sh\n  for i in `ls -1 **/*.png`; do convert $i -background white -alpha remove -alpha off $i; done\n  ```\n\n  [Source](https://stackoverflow.com/a/52962485)\n\n- Export multiple PNG images to PDF using [img2pdf](https://gitlab.mister-muffin.de/josch/img2pdf)\n\n  ```sh\n  # Enter directory containing PNGs\n  cd directory-with-images/\n\n  # Remove alpha from images and convert colorspace to RGB (img2pdf does not support ICC)\n  for i in *.png; convert $i -colorspace rgb -alpha off $i; end\n\n  # Merge images into PDF\n  # (Optional) Add --pagesize A4 to normalize page size\n  img2pdf --output merged.pdf *.png\n\n  # (Optional) To add OCR text layer, execute the following line\n  # ocrmypdf --force-ocr merged.pdf merged.pdf\n  ```\n\n## PDF manipulation\n\n- Add OCR text layer to PDF using [ocrmypdf](https://github.com/jbarlow83/OCRmyPDF)\n\n  ```sh\n  ocrmypdf --force-ocr input.pdf output.pdf\n  ```\n\n- Merge PDFs\n\n  ```sh\n  pdfunite in-1.pdf in-2.pdf out.pdf\n  ```\n\n- Reduce PDF file size\n\n  Requires [`gs`](https://www.ghostscript.com/) and [`shrinkpdf`](http://www.alfredklomp.com/programming/shrinkpdf/) installation\n\n  ```sh\n  shrinkpdf in.pdf out.pdf\n  ```\n\n- Search for text in PDF using [pdfgrep](https://pdfgrep.org/)\n\n  ```sh\n  pdfgrep pattern file.pdf\n  ```\n\n## Optimization\n\n### Parallel\n\n- Run command in parallel using GNU parallel\n\n  ```sh\n  parallel --halt-on-error now,fail=1 'set -o errexit; set -o pipefail; set -o nounset; echo {}' ::: 1 2 3\n  ```\n\n  [Parallel manual](https://www.gnu.org/software/parallel/parallel_tutorial.html)\n\n### Time\n\n- Schedule command execution at specific time and date\n\n  ```sh\n  at hh:mm\n  ```\n\n- Store output of time command in variable without output of argument\n\n  ```sh\n  # Format output of time command\n  # Source: https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#index-TIMEFORMAT\n  TIMEFORMAT='Elapsed time in seconds: %lR'\n\n  # Quoting from http://mywiki.wooledge.org/BashFAQ/032:\n  #   Keep stdout untouched.\n  #   The shell's original file descriptor (FD) 1 is saved in FD 3, which is inherited by the subshell.\n  #   Inside the innermost block, we send the time command's stdout to FD 3.\n  exec 3\u003e\u00261\n  # Captures stderr and time.\n  elapsed_time=$( { time ls 1\u003e\u00263; } 2\u003e\u00261 )\n  exec 3\u003e\u0026-\n  echo \"$elapsed_time\"\n  ```\n\n  [Source](http://mywiki.wooledge.org/BashFAQ/032)\n\n### Copy dirs and files\n\n- Base `rsync` options\n\n  ```sh\n  rsync --archive --compress --verbose --human-readable --progress [PATH] [PATH]\n  ```\n\n- Display overall progress in rsync\n\n  ```sh\n  # Use rsync options --info=progress2 and --no-inc-recursive\n  # Example:\n  cd /tmp/bar \u0026\u0026 find . -type -f | parallel --halt-on-error now,fail=1 -X rsync --relative--no-inc-recursive --info=progress2 --human-readable './{}' /tmp/bar/ ; }\n  ```\n\n- Transfer large files efficiently\n\n  ```sh\n  # Options\n  # WARNING: Add --compress to RSYNC_OPTS only if transferring over a slow connection.\n  # For local transfers --compress actually slows down the operation\n  readonly RSYNC_OPTS=(--hard-links --archive --relative --partial '--info=progress2' --human-readable)\n  readonly RSYNC_EXCLUDES=(--exclude=archive\n    --exclude=.git\n    --exclude=.gitignore\n    --exclude=.idea\n    --exclude=.vagrant\n    --exclude=__pycache__\n    --exclude=*.swp\n    --exclude=.vscode)\n    # 0 jobs in parallel translates to as many as possible\n    readonly NUMBER_OF_JOBS=0\n\n  cd src-dir \u0026\u0026 find . -type f | parallel --jobs \"$NUMBER_OF_JOBS\" --halt-on-error now,fail=1 -X rsync \"${RSYNC_OPTS[@]}\" \"${RSYNC_EXCLUDES[@]}\" ./{} dest-dir/\n  ```\n\n  [Source](https://www.gnu.org/software/parallel/man.html#EXAMPLE:-Parallelizing-rsync)\n\n## String manipulation\n\n- Replace characters in filenames found in current working directory\n\n  ```sh\n  # Replace all occurrences of underscores in filenames of files in current working directory with a hyphen\n  for f in *; do mv $f ${f//_/-}; done\n  ```\n\n## Shell Scripting\n\n- Script template:\n\n  - Robust and [portable](https://www.cyberciti.biz/tips/finding-bash-perl-python-portably-using-env.html) shebang\n  - Recommended bash/shell options for scripts\n  - Inherit shell options in subshells\n\n    [Example](https://stackoverflow.com/a/20832592/2227405) [`SHELLOPTS`\n    docs](https://www.gnu.org/software/bash/manual/html_node/Bash-Variables.html)\n\n  ```sh\n  #!/usr/bin/env bash\n  #\n  # Script description\n\n  # Bash options\n  # Inherit errexit in subshells (requires Bash 4.4+)\n  shopt -s inherit_errexit\n\n  # Shell options\n  set -o errexit\n  set -o pipefail\n  set -o nounset\n\n  # Export enabled shell options to subshells\n  # Documentation:\n  # https://www.gnu.org/software/bash/manual/html_node/Bash-Variables.html\n  export SHELLOPTS\n  ```\n\n- [Bash FAQ](http://mywiki.wooledge.org/BashFAQ)\n\n- [Bash Study Guide](https://fvue.nl/wiki/Bash)\n\n- [Bash variables](https://www.gnu.org/software/bash/manual/html_node/Bash-Variables.html)\n\n- Conditionally pass arguments to command\n\n  ```sh\n  declare conditional_rename=()\n  if [ true ]; then\n    # Including value of variable in case it's not empty\n    conditional_rename=(\"${conditional_rename[@]}\" --before-context=3)\n  fi\n\n  # Converts to grep --before-context=3 'sh' readme.md\n  grep \"${conditional_rename[@]}\" 'sh' readme.md\n  ```\n\n## Related Projects\n\n- [macos-cheatsheet](https://github.com/rodrigobdz/macos-cheatsheet)\n- [modern-unix](https://github.com/ibraheemdev/modern-unix)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frodrigobdz%2Flinux-cheatsheet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frodrigobdz%2Flinux-cheatsheet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frodrigobdz%2Flinux-cheatsheet/lists"}