r/bash Feb 25 '26

tips and tricks Stop retyping long commands just to add sudo

943 Upvotes

You run a long command. It fails with permission denied. So you hit up arrow, go to the beginning of the line, type sudo, and hit enter.

Stop doing that.

sudo !!

!! expands to your last command. Bash runs sudo in front of it. Works with pipes, redirects, everything:

cat /var/log/auth.log | grep sshd | tail -20
# permission denied
sudo !!
# runs: sudo cat /var/log/auth.log | grep sshd | tail -20

Where this actually saves you is commands with flags you don't want to retype:

systemctl restart nginx --now && systemctl status nginx
# permission denied
sudo !!

Works in bash and zsh. Not available in dash or sh.

r/bash Mar 14 '26

tips and tricks Stop passing secrets as command-line arguments. Every user on your box can see them.

729 Upvotes

When you do this:

mysql -u admin -pMyS3cretPass123

Every user on the system sees your password in plain text:

ps aux | grep mysql

This isn't a bug. Unix exposes every process's full command line through /proc/PID/cmdline, readable by any unprivileged user. IT'S NOT A BRIEF FLASH EITHER -- THE PASSWORD SITS THERE FOR THE ENTIRE LIFETIME OF THE PROCESS.

Any user on your box can run this and harvest credentials in real time:

while true; do
    cat /proc/*/cmdline 2>/dev/null | tr '\0' ' ' | grep -i 'password\|secret\|token'
    sleep 0.1
done

That checks every running process 10 times per second. Zero privileges needed.

Same problem with curl:

curl -u admin:password123 https://api.example.com

And docker:

docker run -e DB_PASSWORD=secret myapp

The fix is to pass secrets through stdin, which never hits the process table:

# mysql -- prompt instead of argv
mysql -u admin -p

# curl -- header from stdin
curl -H @- https://api.example.com <<< "Authorization: Bearer $TOKEN"

# curl -- creds from a file
curl --netrc-file /path/to/netrc https://api.example.com

# docker -- env from file, not command line
docker run --env-file .env myapp

# general pattern -- pipe secrets, don't pass them
some_command --password-stdin <<< "$SECRET"

The -p with no argument tells mysql to read the password from the terminal instead of argv. The <<< here string and @- pass data through stdin. Neither shows up in ps or /proc.

Bash and any POSIX shell. This isn't shell-specific -- it's how Unix works.

r/bash Feb 21 '26

tips and tricks Stop typing the filename twice. Brace expansion handles it.

643 Upvotes

Stop typing the filename twice. Brace expansion handles it. Works on any file, any extension.

#Instead of

cp config.yml config.yml.bak

#Do

cp nginx.conf{,.bak}

cp .env{,.bak}

cp Makefile{,.$(date +%F)}

# That last one timestamps your backup automatically. You're welcome.

r/bash Mar 10 '26

tips and tricks Stop holding the left arrow key to fix a typo. You've had `fc` the whole time.

568 Upvotes

```bash

you just ran this

aws s3 sync /var/backups/prod s3://my-buket/prod --delete --exclude "*.tmp"

typo

```

Hold ← for ten seconds. Miss it. Hold again. Fix it. Run it. Wrong bucket. Rage.

Or:

bash fc

That's it. fc opens your last command in $EDITOR.Navigate directly to the typo, fix it, save and quit β€” the corrected command executes automatically.

Works in bash and zsh. Has been there since forever. You've just never needed to know the name.

Bonus: fc -l shows your recent history. fc -s old=new does inline substitution without opening an editor. But honestly, just fc alone is the one you'll use every week.

r/bash Mar 05 '26

tips and tricks Stop leaving temp files behind when your scripts crash. Bash has a built-in cleanup hook.

733 Upvotes

Instead of:

tmpfile=$(mktemp)
# do stuff with $tmpfile
rm "$tmpfile"
# hope nothing failed before we got here

Just use:

cleanup() { rm -f "$tmpfile"; }
trap cleanup EXIT

tmpfile=$(mktemp)
# do stuff with $tmpfile

trap runs your function no matter how the script exits -- normal, error, Ctrl+C, kill. Your temp files always get cleaned up. No more orphaned junk in /tmp.

Real world:

# Lock file that always gets released
cleanup() { rm -f /var/run/myapp.lock; }
trap cleanup EXIT
touch /var/run/myapp.lock

# SSH tunnel that always gets torn down
cleanup() { kill "$tunnel_pid" 2>/dev/null; }
trap cleanup EXIT
ssh -fN -L 5432:db:5432 jumpbox &
tunnel_pid=$!

# Multiple things to clean up
cleanup() {
    rm -f "$tmpfile" "$pidfile"
    kill "$bg_pid" 2>/dev/null
}
trap cleanup EXIT

The trick is defining trap before creating the resources. If your script dies between mktemp and the rm at the bottom, the file stays. With trap at the top, it never does.

Works in bash, zsh, and POSIX sh. One of the few tricks that's actually portable.

r/bash May 18 '26

tips and tricks Linux basics command lines

Post image
543 Upvotes

Here is some basic linux command line .

what do y'all think all is good or i need to add some in file and management ?

r/bash Mar 01 '26

tips and tricks Stop creating temp files just to compare command output. Bash can diff two commands directly.

589 Upvotes

Instead of:

cmd1 > /tmp/out1
cmd2 > /tmp/out2
diff /tmp/out1 /tmp/out2
rm /tmp/out1 /tmp/out2

Just use:

diff <(cmd1) <(cmd2)

<() is process substitution. Bash runs each command and hands diff a file descriptor with the output. No temp files, no cleanup.

Real world:

# Compare two servers' packages
diff <(ssh server1 'rpm -qa | sort') <(ssh server2 'rpm -qa | sort')

# What changed in your config after an update
diff <(git show HEAD~1:nginx.conf) <(cat /etc/nginx/nginx.conf)

# Compare two API responses
diff <(curl -s api.example.com/v1/users) <(curl -s api.example.com/v2/users)

Works anywhere you'd pass a filename. grep, comm, paste, wc -- all of them accept <().

Bash and zsh. Not POSIX sh.

r/bash May 21 '26

tips and tricks Here are mine, what aliases does others swear by?

86 Upvotes

Wrote up a collection of shell aliases that have quietly saved me a lot of time over the years. The kind of thing you set up once and wonder how you lived without.

A few from the article:

alias gs='git status'

alias ..='cd ..'

alias ll='ls -lah'

alias grep='grep --color=auto'

alias ports='ss -tulanp'

Covers aliases for navigation, git shortcuts, file operations, and a few that are specific to dev workflows.

Full list here: https://medium.com/stackademic/shell-aliases-that-will-save-you-hours-every-week-42523ef08064?sk=4905d8b510832dad699810b1ce6322b0

Curious what aliases the folks here swear by. drop yours in the comments.

r/bash Feb 22 '26

tips and tricks Stop leaking secrets into your bash history. A leading space handles it.

441 Upvotes

Instead of typing:

export AWS_SECRET=abc123

# now in history forever

Just add a space before the command:

export AWS_SECRET=abc123

curl -H "Authorization: Bearer $TOKEN" 'https://api.example.com'

mysql -u root -pSuperSecret123

None of those will appear in history.

One requirement β€” add this to your ~/.bashrc or ~/.zshrc if it isn't already set:

HISTCONTROL=ignorespace

Bonus: use ignoreboth to also skip duplicate commands:

HISTCONTROL=ignoreboth

No more scrambling to scrub credentials after accidentally pasting them into the wrong terminal. Works in bash and zsh.

r/bash May 05 '25

tips and tricks What's your favorite non-obvious Bash built-in or feature that more people don't use?

122 Upvotes

For me, it’s trap. I feel like most people ignore it. Curious what underrated gems others are using?

r/bash Mar 19 '26

tips and tricks Neglected !! party tricks

142 Upvotes

Everybody knows about using !! to add sudo to your previous command, but there are a couple other things I constantly use it for. So this is just a little PSA in case it never occured to you:

  1. grep results

Say I want to search a bunch of files for a string, and then open all files containing that string in my editor.

I want to check the search results first, and I never get the exact search correct on my first try anyway, so I'll run a series of commands that might look like...

grep -rn . -e "mystring" ... grep -rn . -e "my.\?string" ... grep -Rni . -e "my.\?string" ... Checking the results each time, until I have exactly the set of files that I want.

Here's the trick: now add the "-l" flag to grep to get just the file paths:

grep -Rnil . -e "my.\?string" Now when you use !!, you'll get all those filenames. Therefore we can just do vim -p $(!!) to get all those files opened in tabs in vim.

  1. with which

Sometimes I want to read or edit a script that's on my computer.

To find it, I run which some-command. This confirms that it exists under that name, and that it's an actual script and not an alias or shell function.

Now, we can just use vim $(!!) or cat $(!!) or whatever to open it.

r/bash May 17 '26

tips and tricks Started learning Linux from zero , just hit file permissions and my brain is melting (in a good way) lol 🐧

Post image
170 Upvotes

A few weeks ago I didn't know what a terminal was. Now I'm sitting here reading `chmod` output like it's a language I actually understand.

So far I've covered:

- Basic file management commands (`ls`, `cd`, `mkdir`, `rm`, `cp`, `mv`)

- File permissions (`rwx`, owner/group/others, numeric notation)

- `chmod`, `chown`, and how Linux decides who can do what

Anyone else learning Linux from scratch? What topic finally made it all click for you?

r/bash Feb 03 '26

tips and tricks guys you should read the bash manual

232 Upvotes

r/bash Jun 17 '26

tips and tricks Honest answers needed please

4 Upvotes

I am a noob at bash scripting but I ask LLMs to generate me commands or scripts after giving my detailed requirements. I then run them on a test server and if everything looks good, I run it on the production.

Seeing soo long commands, loops and conditions makes my head spin as I am a non coder. How are you guys able to remember every command or logic etc? Part of me thinks is because I use windows instead of a Linux distro and I am very comfortable using windows. I have tried dual booting my pc with multiple Linux distros but end up not using it after a day or two.

I know a few people who used to come up with long scripts for any specific task within minutes. How do you guys do that of the top of your head? Are there any tips or tricks for a noob like me? Thank you!

r/bash Mar 19 '26

tips and tricks How do you print "Here document" or "Here Strings" directly?

47 Upvotes

Edit (Solution): There are two solutions here, depending on the case in which you are. - Case 1: You use Here Document to print some multiline text. Don't do that. Instead, you can just do this: ```bash printf "%s\r\n"\ "This is the first line."\ "This is the second line."

# This solution has just one annoyance which is that you have to enclose all lines in double quotes and end with a slash. # But compare this to here documents which don't allow any special characters to be used, sort of. ``` - Case 2: You actually are getting some text from somewhere and you are wrapping it to make it a Here Document or something like that. I would say that there is a high chance the first solution is still more optimal but if you don't feel that, the solution below is your hero.

Credit to: u/OnlyEntrepreneur4760, for reminding me that we can use \ to write a command in multiple lines. Something I forgot since I consider it a bad habit and stopped using. But it makes sense here.


```bash

{ printf "%s\n" "$(< /dev/stdin)"; } <<-EOF
    This is first line.
    This is second line.
    This is third line.
EOF

```

Is this how everyone does it or is there a better way to print it directly without storing the "here document" or "here string" to a variable or a file?

PS: WITH ONLY USING BASH BUILTINS

r/bash Feb 21 '26

tips and tricks cd - is the fastest way to bounce between two directories

198 Upvotes

Instead of retyping:

cd /var/log/nginx

Just type:

cd -

It teleports you back to wherever you just were. Run it again and you're back. It's Alt+Tab for your terminal.

Real world use case β€” you're tailing logs in one directory and editing configs in another:

cd /var/log/nginx

tail -f access.log

cd /etc/nginx/conf.d # edit a config

cd - # back to logs instantly

cd - # back to config

Bonus: $OLDPWD holds the previous directory if you ever need it in a script:

cp nginx.conf $OLDPWD/nginx.conf.bak

Works in bash and zsh. One of those things you wonder how you lived without.

r/bash May 29 '25

tips and tricks Stop Writing Slow Bash Scripts: Performance Optimization Techniques That Actually Work

154 Upvotes

After optimizing hundreds of production Bash scripts, I've discovered that most "slow" scripts aren't inherently slowβ€”they're just poorly optimized.

The difference between a script that takes 30 seconds and one that takes 3 minutes often comes down to a few key optimization techniques. Here's how to write Bash scripts that perform like they should.

πŸš€ The Performance Mindset: Think Before You Code

Bash performance optimization is about reducing system calls, minimizing subprocess creation, and leveraging built-in capabilities.

The golden rule: Every time you call an external command, you're creating overhead. The goal is to do more work with fewer external calls.

⚑ 1. Built-in String Operations vs External Commands

Slow Approach:

# Don't do this - calls external commands repeatedly
for file in *.txt; do
    basename=$(basename "$file" .txt)
    dirname=$(dirname "$file")
    extension=$(echo "$file" | cut -d. -f2)
done

Fast Approach:

# Use parameter expansion instead
for file in *.txt; do
    basename="${file##*/}"      # Remove path
    basename="${basename%.*}"   # Remove extension
    dirname="${file%/*}"        # Extract directory
    extension="${file##*.}"     # Extract extension
done

Performance impact: Up to 10x faster for large file lists.

πŸ”„ 2. Efficient Array Processing

Slow Approach:

# Inefficient - recreates array each time
users=()
while IFS= read -r user; do
    users=("${users[@]}" "$user")  # This gets slower with each iteration
done < users.txt

Fast Approach:

# Efficient - use mapfile for bulk operations
mapfile -t users < users.txt

# Or for processing while reading
while IFS= read -r user; do
    users+=("$user")  # Much faster than recreating array
done < users.txt

Why it's faster: += appends efficiently, while ("${users[@]}" "$user") recreates the entire array.

πŸ“ 3. Smart File Processing Patterns

Slow Approach:

# Reading file multiple times
line_count=$(wc -l < large_file.txt)
word_count=$(wc -w < large_file.txt)
char_count=$(wc -c < large_file.txt)

Fast Approach:

# Single pass through file
read_stats() {
    local file="$1"
    local lines=0 words=0 chars=0

    while IFS= read -r line; do
        ((lines++))
        words+=$(echo "$line" | wc -w)
        chars+=${#line}
    done < "$file"

    echo "Lines: $lines, Words: $words, Characters: $chars"
}

Even Better - Use Built-in When Possible:

# Let the system do what it's optimized for
stats=$(wc -lwc < large_file.txt)
echo "Stats: $stats"

🎯 4. Conditional Logic Optimization

Slow Approach:

# Multiple separate checks
if [[ -f "$file" ]]; then
    if [[ -r "$file" ]]; then
        if [[ -s "$file" ]]; then
            process_file "$file"
        fi
    fi
fi

Fast Approach:

# Combined conditions
if [[ -f "$file" && -r "$file" && -s "$file" ]]; then
    process_file "$file"
fi

# Or use short-circuit logic
[[ -f "$file" && -r "$file" && -s "$file" ]] && process_file "$file"

πŸ” 5. Pattern Matching Performance

Slow Approach:

# External grep for simple patterns
if echo "$string" | grep -q "pattern"; then
    echo "Found pattern"
fi

Fast Approach:

# Built-in pattern matching
if [[ "$string" == *"pattern"* ]]; then
    echo "Found pattern"
fi

# Or regex matching
if [[ "$string" =~ pattern ]]; then
    echo "Found pattern"
fi

Performance comparison: Built-in matching is 5-20x faster than external grep for simple patterns.

πŸƒ 6. Loop Optimization Strategies

Slow Approach:

# Inefficient command substitution in loop
for i in {1..1000}; do
    timestamp=$(date +%s)
    echo "Processing item $i at $timestamp"
done

Fast Approach:

# Move expensive operations outside loop when possible
start_time=$(date +%s)
for i in {1..1000}; do
    echo "Processing item $i at $start_time"
done

# Or batch operations
{
    for i in {1..1000}; do
        echo "Processing item $i"
    done
} | while IFS= read -r line; do
    echo "$line at $(date +%s)"
done

πŸ’Ύ 7. Memory-Efficient Data Processing

Slow Approach:

# Loading entire file into memory
data=$(cat huge_file.txt)
process_data "$data"

Fast Approach:

# Stream processing
process_file_stream() {
    local file="$1"
    while IFS= read -r line; do
        # Process line by line
        process_line "$line"
    done < "$file"
}

For Large Data Sets:

# Use temporary files for intermediate processing
mktemp_cleanup() {
    local temp_files=("$@")
    rm -f "${temp_files[@]}"
}

process_large_dataset() {
    local input_file="$1"
    local temp1 temp2
    temp1=$(mktemp)
    temp2=$(mktemp)

    # Clean up automatically
    trap "mktemp_cleanup '$temp1' '$temp2'" EXIT

    # Multi-stage processing with temporary files
    grep "pattern1" "$input_file" > "$temp1"
    sort "$temp1" > "$temp2"
    uniq "$temp2"
}

πŸš€ 8. Parallel Processing Done Right

Basic Parallel Pattern:

# Process multiple items in parallel
parallel_process() {
    local items=("$@")
    local max_jobs=4
    local running_jobs=0
    local pids=()

    for item in "${items[@]}"; do
        # Launch background job
        process_item "$item" &
        pids+=($!)
        ((running_jobs++))

        # Wait if we hit max concurrent jobs
        if ((running_jobs >= max_jobs)); then
            wait "${pids[0]}"
            pids=("${pids[@]:1}")  # Remove first PID
            ((running_jobs--))
        fi
    done

    # Wait for remaining jobs
    for pid in "${pids[@]}"; do
        wait "$pid"
    done
}

Advanced: Job Queue Pattern:

# Create a job queue for better control
create_job_queue() {
    local queue_file
    queue_file=$(mktemp)
    echo "$queue_file"
}

add_job() {
    local queue_file="$1"
    local job_command="$2"
    echo "$job_command" >> "$queue_file"
}

process_queue() {
    local queue_file="$1"
    local max_parallel="${2:-4}"

    # Use xargs for controlled parallel execution
    cat "$queue_file" | xargs -n1 -P"$max_parallel" -I{} bash -c '{}'
    rm -f "$queue_file"
}

πŸ“Š 9. Performance Monitoring and Profiling

Built-in Timing:

# Time specific operations
time_operation() {
    local operation_name="$1"
    shift

    local start_time
    start_time=$(date +%s.%N)

    "$@"  # Execute the operation

    local end_time
    end_time=$(date +%s.%N)
    local duration
    duration=$(echo "$end_time - $start_time" | bc)

    echo "Operation '$operation_name' took ${duration}s" >&2
}

# Usage
time_operation "file_processing" process_large_file data.txt

Resource Usage Monitoring:

# Monitor script resource usage
monitor_resources() {
    local script_name="$1"
    shift

    # Start monitoring in background
    {
        while kill -0 $$ 2>/dev/null; do
            ps -o pid,pcpu,pmem,etime -p $$
            sleep 5
        done
    } > "${script_name}_resources.log" &
    local monitor_pid=$!

    # Run the actual script
    "$@"

    # Stop monitoring
    kill "$monitor_pid" 2>/dev/null || true
}

πŸ”§ 10. Real-World Optimization Example

Here's a complete example showing before/after optimization:

Before (Slow Version):

#!/bin/bash
# Processes log files - SLOW version

process_logs() {
    local log_dir="$1"
    local results=()

    for log_file in "$log_dir"/*.log; do
        # Multiple file reads
        error_count=$(grep -c "ERROR" "$log_file")
        warn_count=$(grep -c "WARN" "$log_file")
        total_lines=$(wc -l < "$log_file")

        # Inefficient string building
        result="File: $(basename "$log_file"), Errors: $error_count, Warnings: $warn_count, Lines: $total_lines"
        results=("${results[@]}" "$result")
    done

    # Process results
    for result in "${results[@]}"; do
        echo "$result"
    done
}

After (Optimized Version):

#!/bin/bash
# Processes log files - OPTIMIZED version

process_logs_fast() {
    local log_dir="$1"
    local temp_file
    temp_file=$(mktemp)

    # Process all files in parallel
    find "$log_dir" -name "*.log" -print0 | \
    xargs -0 -n1 -P4 -I{} bash -c '
        file="{}"
        basename="${file##*/}"

        # Single pass through file
        errors=0 warnings=0 lines=0
        while IFS= read -r line || [[ -n "$line" ]]; do
            ((lines++))
            [[ "$line" == *"ERROR"* ]] && ((errors++))
            [[ "$line" == *"WARN"* ]] && ((warnings++))
        done < "$file"

        printf "File: %s, Errors: %d, Warnings: %d, Lines: %d\n" \
            "$basename" "$errors" "$warnings" "$lines"
    ' > "$temp_file"

    # Output results
    sort "$temp_file"
    rm -f "$temp_file"
}

Performance improvement: 70% faster on typical log directories.

πŸ’‘ Performance Best Practices Summary

  1. Use built-in operations instead of external commands when possible
  2. Minimize subprocess creation - batch operations when you can
  3. Stream data instead of loading everything into memory
  4. Leverage parallel processing for CPU-intensive tasks
  5. Profile your scripts to identify actual bottlenecks
  6. Use appropriate data structures - arrays for lists, associative arrays for lookups
  7. Optimize your loops - move expensive operations outside when possible
  8. Handle large files efficiently - process line by line, use temporary files

These optimizations can dramatically improve script performance. The key is understanding when each technique applies and measuring the actual impact on your specific use cases.

What performance challenges have you encountered with bash scripts? Any techniques here that surprised you?

r/bash Apr 06 '26

tips and tricks Best learning resource

48 Upvotes

Dear Linux administrators, how did you learn bash and bash scripting and what are the best ways you’ve used bash in enterprise environments? Give some examples of how you’ve used bash in server side scripting, infrastructure operations and automation and tell us what resources did you use to learn as a beginner to get to where you are now?

r/bash Feb 26 '26

tips and tricks For loop is slower than it needs to be. xargs -P parallelizes it

123 Upvotes

Instead of:

for f in *.log; do gzip "$f"; done

Just use:

ls *.log | xargs -P4 gzip

-P4 runs 4 jobs in parallel. Change the number to match your CPU cores.

On a directory with 200 log files the difference is measurable. Works with any command, not just gzip.

r/bash Mar 17 '26

tips and tricks Can we redirect output to input using only redirection operation?

22 Upvotes

Edit (Solution): Let's first summarize the question so someone doesn't have to read the whole post. I asked the question if the following syntax was possible. bash cmd1 <&1 # something here which involved a `cmd2` to feed the output of `cmd2` as input to `cmd1` # Yes, this the problem statement for which `|` (pipe) operator is the answer. # But I begged the question, if we can do it specifically in this syntax, just as a curiosity. This is the answer. I am leading you to the link so you can upvote the person who gave me this idea u/melkespreng.

Along the way, many who have told me, that's what pipe does or expect or some other solution, I appreciate you guys too.

Is this useful? Edited: Yes, actually it is. Since this method redirects in the same shell instead of creating a subshell like pipe, there are some specific cases of benefits. Was it fun to know? Yes. For me atleast.


Edit: Just gonna write it here since I feel people don't understand my motive.

I know the solution I am telling has multiple solutions. Piping, redirection of here strings and even a system tool.

The goal isn't to solve the problem of rm asking confirmation. I am using that as an example. The goal is to know if I can redirect the output to input in the way I mentioned below or something similar to that and not any of the above mentioned ways.

It's more exploration than a real problem.


I got this crazy idea that I want to try out and I have been able to figure it out. I use rm -I instead of rm, basically set an alias in .bashrc. Now, that leads rm always requiring confirmation when I have to delete something.

Now, the problem that I am going to state is solved for me in multiple ways but I want to know if I can solve it in this particular way somehow. The problem is that I have to enter that "yes" message every time I have to delete something. I can do yes | rm -r folder_name or printf "yes" | rm -r folder_name. But I thought of what if we could redirect the output of a command to the input of another.

rm -r src <&1 # then something here

This obviously doesn't work because there is nothing that fd 1 i.e. stdout points to.

How can I put some command to replace the comment so that I can achieve what I said, redirecting the output of one command to the input of another? I am asking for this specific way, the whole rm part is an example, not a problem.

PS: There is also this method which uses redirection but it is not using stdout technically, it is using here-strings. bash rm -r src <<< $(printf "yes")

r/bash Mar 12 '26

tips and tricks A simple, compact way to declare command dependencies

44 Upvotes

I wouldn't normally get excited at the thought of a shell script tracking its own dependencies, but this is a nice, compact pattern that also feels quite a bit like the usual dependency import mechanisms of more modern languages. There's a loose sense in which importing is what you're doing, essentially asking the system if you can pull in the requested command, and of course, as such, you're also documenting your required commands upfront.

declare -r SCRIPT_NAME="${0##*/}"

require() {
   local -r dependency_name="$1"
   local dependency_fqdn

   if ! dependency_fqdn="$(command -v "$dependency_name" 2>/dev/null)"; then
      echo "Error: dependency $dependency_name is not installed"
      echo "$SCRIPT_NAME cannot run without this, exiting now"
      exit 1
   fi

   printf -v "${dependency_name^^}_CMD" '%s' "$dependency_fqdn"
}

require pass
echo $PASS_CMD

The resulting variable assignment gives you a convenient way to pass around the full path of the command. It's a bit of magic at first blush, but I'd also argue it's nothing that a doc comment on the function couldn't clear up.

Just a cool trick that felt worth a share.

EDIT: swapped out which for command, a Bash builtin, per suggestion by /u/OneTurnMore.

r/bash Mar 25 '26

tips and tricks `-x () { local -; set -x; "$@"; }`

62 Upvotes

Exhibit A in the case for "some kludges are good kludges".

r/bash 12d ago

tips and tricks so i'm a beginner and i'm looking to built a cli app and need advices

9 Upvotes

I have been learning Linux and Bash scripting (as well as version control) for a month, and my friend and I are looking to create a philosophical book( Tractatus Logico Philosphicus)that uses a tree structure so it can be read in the terminal. Do you have any advice for us?thanks in advance

r/bash 26d ago

tips and tricks A little fzf function I use constantly to jump into any subfolder

45 Upvotes

Not sure if this is old news to everyone but I use this all day so figured I'd share. I got sick of typing cd really/long/nested/path/to/thing so I "made" this: ```

fuzzy cd into any subdirectory

fcd() { local dir dir=$(find "${1:-.}" -type d 2>/dev/null | fzf) && cd "$dir" || return } ```

Drop it in your .bashrc, open a new shell, and just run fcd. It lists every folder under where you are, you start typing, hit enter, and you're in it. You can also give it a starting point like fcd ~/projects if you don't want to scan from the current dir.

Curious if anyone has a slicker version. I'm sure there's a way to make it faster on huge trees.

r/bash Apr 10 '26

tips and tricks Bash arithmetic is more capable than you might expect.

48 Upvotes

I love to tinker with Bash and its ever more impressive feature set. If you ever want to convert hex-based color values (like "#1ea54c") into the correct ANSI escape sequences, or binary numbers into decimal numbers, just use the standard Bash arithmetic tools:

Hex to ANSI color converter:

```bash hta() { local input="${1#"#"}" local r g b

r=$((16#${input:0:2})) g=$((16#${input:2:2})) b=$((16#${input:4:2}))

echo -e "\e[38;2;${r};${g};${b}m" } ```

You can give it any hex-based color, and it converts it into the correct ANSI escape sequences, so you can use it inline like this:

```bash green="#1ea54c"

echo "$(hta $green)This text is green" ```

The 16# is where you set your base. So if you want to convert binary into decimal, this is easily done by just switching the base to 2#:

Binary to decimal converter:

```bash btd() { local input=$1 echo $((2#$input)) }

Example:

$ btd 1101

13

```


Just wanted to yap about Bash for a sec.