r_bash | Unsorted

Telegram-канал r_bash - r_bash

46

Credits: @r_channels & @reddit2telegram

Subscribe to a channel

r_bash

RemZero | A bootstrap script
https://redd.it/1wc94qe
@r_bash

Читать полностью…

r_bash

Help running a shell script in apple terminal

Using Composers Desktop Project to edit audio files. I want to run a single command on a list of audio files instead of having to manually do it 100 times. Wondering if there is a way to call upon this list of files in a single command line, rather than creating a shell script with the name of every file. The command line with a single audio file would look like this.

distort average soundfile.wav soundfileoutput.wav

the first two words are the command being run and then the input and output respectively. Hopefully I provided enough info on this but also relatively new to using terminal so let me know if there is anything I should clarify, thanks.

https://redd.it/1wfnebe
@r_bash

Читать полностью…

r_bash

Maybe powerlevel10k-style prompts for bash

I've been happily using powerlevel10k with zsh. If you've never used p10k, it's the prompt a lot of zsh users swear by, and plenty of bash users wish they had it too. The catch: p10k is zsh-only, and it's now in maintenance mode.

So I wrote p11k, a cross-shell prompt engine in Rust inspired by p10k. It doesn't work like Starship. Starship is a program your shell calls while rendering the prompt. p11k sits between your terminal and your shell as a transparent proxy. It starts your shell in its own pty and draws the prompt itself. It's more involved, but it also lets you do some things other prompts can't, like instant prompt. Being a separate engine doesn't make it slow, either. Honestly, when I had p10k and p11k open side by side in two windows, I couldn't tell them apart at all, and neither could a couple of friends who use p10k every day.

It covers most of what p10k does, and the same smart directory truncation. The config is KDL v2 instead of a pile of PS1 escapes, and there's a setup wizard like p10k configure.

It's a personal project, but if you miss powerlevel10k, I'd love for you to check it out.

Heads up: Linux only for now.

Powerlevel11k

Thanks for reading.

p11k with bash

https://redd.it/1wgm9d6
@r_bash

Читать полностью…

r_bash

Great things about bash?

If is easy to read bad things about bash (and often with good reason). Clearly a bash script will never look as elegant as, say, Ruby.

But what about great things about bash? I mean, "great", not in the sense of improving over a POSIX shell, but of being elegant and/or comparing well with (some well-known) "real" programming languages. Here are my two favorites

the OR list operator, e.g:

​

[[ condition ]] || {
actions...
}


(more elegant than an "if not"... conditional)

the ability to assign a command name to a variable, var="command --option1 --option2 ...", then execute the command later with:

​

$cmd

(unquoted to allow the options to appear as separate words).

What about your favorites?

https://redd.it/1wi7285
@r_bash

Читать полностью…

r_bash

around shift is built becomes slow, as you end up passing arguments to each function. In many cases it is faster to copy arguments once to an array args=("$@") and have an global shared iterator args_i iterating over args array.

Sparse arrays in bash are represented as a linked list with an additional "last used" element. Each element has a pointer to the next and previous element, and each array element stores the index and value. Additionally "last used" pointer to element is used. When accessing an array of some index, Bash checks which pointer to use to get there faster - from the first, last or last used element - and then traverses the linked list until the element of specified index is found. This opens several preferred array access patterns. Random access is slow. It is fast to iterate over the array - from the back, from the front, from the last used element. If you have some work to do on sparse arrays, prefer to put related data in close-by indexes instead of scattering them.

In many cases, it is possible to use some tricks to speed up execution. For example instead of a boring for ((i=X;i<Y;++I)) to iterate over elements from X to Y in many cases it is possible to use eval ...{$X..$Y}... \- use {X..Y} expansion with prepared quoted code. However, this is not always faster and requires profiling. Eval is slow, it is parsing the expression inside. More often then it might be actually faster to write a boring loop iterating over elements then depending on clever tricks.

However, more often then not, reducing the number of commands is profitable. For example lets take a boring eval "$expr" example. If expression is often empty, this executes eval doing nothing. You can write ${expr:+eval} ${expr:+"$expr"} and execute "nothing" (literally nothing, nothing shows up in set -x) when expr is empty or unset. Knowledge of expansions comes handy, and recent ${var@Q} ${arr@k} ${var@a} might be useful.

Similarly, you can do side effects in arithmetic contexts in array subscripts. So arr[i]=...; i=$((i+1)) is just arr[i++]=...;. But with comma operator you can do anything inside arithmetic context. So following that arr[i++]=...; var=2 can be joined together arr[var = 2, i++]=.... Effective everything can be "squeezed" inside one arithmetic context together. Also this is cheaper eval. Arithmetic expansion first expands the input and then calculates. So you can sum arguments with IFS=+; (( $* )) and similar tricks that work really first.



https://redd.it/1wiatqj
@r_bash

Читать полностью…

r_bash

How to Write Regular Expressions (With a Live Tester)
https://ommais.com/blog/how-to-write-regular-expressions/

https://redd.it/1wxu3m8
@r_bash

Читать полностью…

r_bash

I made a package manager in bash!

Its called scrapre. It doesn't have any cryptographic verification so note that (please note that) and there is no repository up for it right now cuz I dont really have much need to host one. You cant find it here. (its codeberg btw)

https://redd.it/1wjsrlo
@r_bash

Читать полностью…

r_bash

Made a neat little function out of an alias

Came across a little alias that basically just lists out only the dotfiles in the cwd, and wanted to make it work for any directory, but also gives you a count of how many dotfiles are in that directory if, for some reason you need that, so I turned it into a function.

ldot() {
if "$1" == "-c" ; then
shift
ls -AF "$@" | grep -E '^\.' | wc -l
else
ls -AF "$@" | grep -E '^\.'
fi
}



https://redd.it/1wkmwi1
@r_bash

Читать полностью…

r_bash

using bash to make a random password?

hello, i heard that you can make a random password with bash? is that true? if so, how do you do that? thank you

https://redd.it/1wljjq1
@r_bash

Читать полностью…

r_bash

I made a little bash-perl heredoc that intends to be a bit better than envsubst.

I had been working with envsubst for some months and was fed up by its limitation to parse multiple files at once. It required a for loop just to parse those files and thus, I have created some bash-perl heredoc for the workaround. It is about 2.5K lines. This is intended to replace Envsubst for my system. (Envsubst++ for me)

    mkdir -p templates
cat > templates/greeting.dcol <<'EOF'
$PATH:[::HOME::]/.config/demo/greeting.conf
# Generated by hyir from [::_SOURCE_BASENAME::] -- do not edit by hand
user = [::USER::]
greeting = "Hello, [::NAME:-world::]!"
EOFmkdir -p templates
cat > templates/greeting.dcol <<'EOF'
$PATH:[::HOME::]/.config/demo/greeting.conf
# Generated by hyir from [::_SOURCE_BASENAME::] -- do not edit by hand
user = [::USER::]
greeting = "Hello, [::NAME:-world::]!"
EOF

**Render it.** Placeholders are filled in from the environment.

NAME=Ada hyir.sh templates/
cat ~/.config/demo/greeting.conf

# GeneRender it. Placeholders are filled in from the environment.
NAME=Ada hyir.sh templates/
cat ~/.config/demo/greeting.conf






    # Generated by hyir from greeting.dcol -- do not edit by hand
user = alice
greeting = "Hello, Ada!"
rated by hyir from greeting.dcol -- do not edit by hand
user = alice
greeting = "Hello, Ada!"


3. Run it again. Nothing changed, so nothing is rewritten. Add --allow-debug to see what hyir decided:
NAME=Ada hyir.sh --allow-debug templates/

############
@[populate:write(false)]: Skipped changing /home/alice/.config/demo/greeting.conf <- templates/greeting.dcol
@[diagnostic:telemetry(On)]: Rendered 1 templates using 1 workers in 0.0026 seconds (all succeeded).


### Header
$PATH:<target>|$REQUIRE:{VAR1,VAR2}|$PRE:{hook}|$RUN:{hook}


The header is the first line of the file. When a value is wrapped in { ... } it may span several lines (braces are matched properly, including nested ones). Segments are separated by |. Only $PATH is required. Put $RUN last: it may itself contain | (for example a shell pipeline), so it absorbs everything after it.




If we want to write the template into a multiple file:
  
$PATH:{[::HOME::]/TEMP, [::HOME::]/TEMP1}


The flag --proc [N|auto] renders in parallel worker processes. Output stays deterministic: templates that resolve to the same target are grouped onto one worker and processed in order.

Fallbacks is also part of the script:
$PATH:[::NAME:-default::]

[::PLACEHOLDER:-SOME_ANOTHER::]


It is an independent script that can be adopted into any environment where it requires config generations, do runtime-template polymorphism (I am not sure if it is accurate enough to say 'polymorphism') and use it for kubernets, etc. Feel free to check out.

github: https://github.com/valkyrieAttr/HyIR.git

https://redd.it/1wn0hxo
@r_bash

Читать полностью…

r_bash

Do you guys think there is a more concise way to write these functions?


# https://linux.die.net/man/8/usermod
function install_docker() {
validate_arg_min_count "${FUNCNAME[0]}" 3 "$#" "Usage: ${FUNCNAME[0]} <debug> <version> <user>" || return 1

local -r debug="${1:-false}"
local -r version="$2"

local -r user="$3"
shift 3

validate_arg_not_empty "${FUNCNAME[0]}" "debug" "${debug}" || return 1
validate_arg_not_empty "${FUNCNAME[0]}" "version" "${version}" || return 1
validate_arg_not_empty "${FUNCNAME[0]}" "user" "${user}" || return 1

validate_arg_type_boolean "${FUNCNAME[0]}" "debug" "${debug}" || return 1

if dnf install "docker-${version}" \
--assumeyes \
--quiet; then
[[ "${debug}" = "true" ]] && log_info "docker installation successful $(docker --version)"
else
log_error "docker installation failed"
return 1
fi

if usermod --append --groups docker "${user}"; then
[[ "${debug}" = "true" ]] && log_info "adding user:${user} to the docker group successful"
else
log_error "adding user:${user} to the docker group failed"
return 1
fi

if newgrp docker; then
[[ "${debug}" = "true" ]] && log_info "changes to docker group successful"
else
log_error "changes to docker group failed"
return 1
fi

if systemctl enable docker.service &&
systemctl start docker.service; then
[[ "${debug}" = "true" ]] && log_info "starting docker service successful"
else
log_error "starting docker service failed"
return 1
fi
}

# Install docker-compose
# Don't use chmod u+x here since it runs as root
# https://github.com/amazonlinux/amazon-linux-2023/issues/1032#issuecomment-3674146092
function install_docker_compose() {
validate_arg_min_count "${FUNCNAME[0]}" 2 "$#" "Usage: ${FUNCNAME[0]} <debug> <version>" || return 1

local -r debug="${1:-false}"
local -r url="$2"
shift 2

validate_arg_not_empty "${FUNCNAME[0]}" "debug" "${debug}" || return 1
validate_arg_not_empty "${FUNCNAME[0]}" "url" "${url}" || return 1

validate_arg_type_boolean "${FUNCNAME[0]}" "debug" "${debug}" || return 1

if curl \
--location "${url}" \
--output "/usr/local/bin/docker-compose" \
--show-error \
--silent; then
[[ "${debug}" = "true" ]] && log_info "Download for docker-compose successful, version:$(docker-compose --version)"
else
log_error "Download for docker-compose failed"
return 1
fi

if chmod +x /usr/local/bin/docker-compose; then
[[ "${debug}" = "true" ]] && log_info "Permission grant to execute docker compose by ec2-user successful"
else
log_error "Permission grant to execute docker compose by ec2-user failed"
return 1
fi
}

function install_git() {
validate_arg_min_count "${FUNCNAME[0]}" 2 "$#" "Usage: ${FUNCNAME[0]} <debug> <version>" || return 1

local -r debug="${1:-false}"
local -r version="$2"
shift 2

validate_arg_not_empty "${FUNCNAME[0]}" "debug" "${debug}" || return 1
validate_arg_not_empty "${FUNCNAME[0]}" "version" "${version}" || return 1

validate_arg_type_boolean "${FUNCNAME[0]}" "debug" "${debug}" || return 1

if dnf install "git-${version}" \
--assumeyes \
--quiet; then
[[ "${debug}" = "true" ]] && log_info "git installation successful $(git --version)"
else
log_error "git installation failed"
return 1
fi
}

function install_jq() {
validate_arg_min_count "${FUNCNAME[0]}" 2 "$#" "Usage: ${FUNCNAME[0]} <debug> <version>" || return 1

local -r debug="${1:-false}"
local -r version="$2"
shift 2

validate_arg_not_empty "${FUNCNAME[0]}" "debug" "${debug}" || return 1
validate_arg_not_empty "${FUNCNAME[0]}" "version" "${version}" || return 1

validate_arg_type_boolean "${FUNCNAME[0]}" "debug" "${debug}" || return 1

if dnf install "jq-${version}" \
--assumeyes \
--quiet; then
[[ "${debug}" = "true" ]] && log_info "jq installation successful $(jq --version)"
else
log_error "jq installation failed"
return 1
fi
}



- Some of them are doing literally the same thing like installing git and jq and yet others in the name of installing are doing slightly different stuff
- There is also a tonne of validation checks everywhere.

Читать полностью…

r_bash

pdfmt - I wrote a multi tool, cause I got tired of manual duplex scanning for my family's paperwork

Taking over the paperwork for my aging parents meant dealing with a mountain of legacy documents and a Brother ADF scanner that is quite fast but only supports simplex. Being happily frugal, I wasn't about to drop money on a new duplex scanner while my current hardware works totally fine. Handling mixed stacks of single- and double-sided pages through GUI tools became a massive time bottleneck.

So, I wrote several simple scripts to do the dirty work for me. All those scripts evolved into a lightweight, transparent CLI tool to automate the work without any heavy frameworks or bloat.

Instead of clicking through endless menus, moving pages in previews, and so on I can now process stacks right from the terminal with an easy interface:

# Example 1:
# Scan a stack of 1-page documents (invoices, delivery notes, etc.) via ADF and split it into individual files with prefix "invoice_"
# Workflow:
# - scan all invoices
# - split all pages into individual files with prefix "invoice_"

pdfmt scan adf invoices.pdf
pdfmt split all invoices.pdf invoice_



# Example 2:
# Scan a stack of 2-sided documents (1 physical sheet, printed on both sides), but your scanner _DOES NOT_ have a duplex ADF.
# Workflow:
# - scan all front sides
# - flip the stack over, put it back in the ADF, and scan the back sides
# - merge both files in correct page order
# - split the result into chunks of 2 pages with prefix document_

pdfmt scan adf front.pdf
pdfmt scan adf back.pdf
pdfmt merge duplex front.pdf back.pdf documents.pdf
pdfmt split length 2 documents.pdf document_

It's built for a real-world workflow to handle thousands of documents, saved me weeks of time, works on Linux, macOS (and WSL) and you can easily integrate it into your own scripts and workflows. There are more features in this tool, check out the readme.

If you deal with similar paper hell or just like simple CLI tools, check it out here:

👉 [https://www.github.com/eifelcode/pdfmt](https://www.github.com/eifelcode/pdfmt)

I'm also open for feedback on how to improve my script, architecture and workflow. =)


AI notice: AI (mistral) was used to generate parts of the [README.md](http://README.md), the .github workflow, the code coverage tool, and parts of the unit tests in the tests/ folder. Architecture, Makefile, and code within the sources/ folder is written by me

https://redd.it/1wfi4eg
@r_bash

Читать полностью…

r_bash

I finally organized my Bash config

I've been accumulating my Bash configuration for a while, and I finally turned it into a small dotfiles repo:

https://gitlab.com/letmevi/bash-config

It's nothing fancy — mainly my .bashrc, .inputrc, .bash_profile, and a modular .bashrc.d/, plus a small install script.

It can be installed using either Ansible or a simple `install.sh` script.

I'd appreciate some Bash/Linux feedback: things you'd change, questionable practices, portability issues, or just better ways of doing this.

I'm especially interested in feedback from people who maintain their own dotfiles.

https://redd.it/1wfp780
@r_bash

Читать полностью…

r_bash

Which is the better Terminal ZSH vs BASH

Any one?

https://redd.it/1w70c90
@r_bash

Читать полностью…

r_bash

Ctrl+D then Ctrl+C weird behaviour in heredoc?

Hello guys, anybody knows why this happens in bash?

If i an running for example: cat << a

Then i press Ctrl+D (inside the heredoc)

After this i return to the prompt, then immediately i press Ctrl+C

The behavior after the sigint is a new empty line then a new line containing the prompt. Does anyone knkw why it is printing an empty new line? In every other case it doesnt print a new empty line and i searched and asked two llms and nothing answered my question

Thanks for your help

https://redd.it/1vx6d1u
@r_bash

Читать полностью…

r_bash

What is a clean Bash pattern for resuming a partially completed batch?

Suppose a Bash script walks thousands of independent inputs and may be interrupted after some outputs have been written. Skipping every existing output is unsafe because a truncated file also exists, while restarting the whole batch wastes work and can repeat external side effects.

A pattern I am considering is to write each result to a temporary file in the destination directory, validate it, rename it atomically, and then append the input ID plus an output hash to a journal. On restart, the script would trust only journal entries whose current hash still matches. A lock would prevent overlapping runs, and traps would clean only the current process's temporary files.

Where does this pattern fail in Bash, especially with parallel workers, NFS, or a crash between the rename and journal append? Is there a simpler checkpoint design that remains understandable without turning the script into a database application?

https://redd.it/1wd5830
@r_bash

Читать полностью…

r_bash

My first Bash Script

Hello, I started learning Bash 2 years ago but I didn't really tried to learn it in this 2 years. I actually started using Linux 2 years ago but never tried Bash. 1 or 2 weeks ago I tried writing my first if statement, after that I tried learning more. This is my first project, transfer part is still not yet done but it's mostly over so that's why I wanted to post this. I'd be very happy if anyone could tell me how to make this better.


https://github.com/molbegigib-ops/MemiBank

https://redd.it/1wfdfyl
@r_bash

Читать полностью…

r_bash

One of the big things that bugs me in bash is how to write those boolean check_, exists_ type of functions, any standard practices?

```
#!/usr/bin/env bash

function is_existing_docker_network() {
local -r debug="${1:-false}"
local -r network_name="$2"

if docker network inspect "${network_name}" >/dev/null 2>&1; then
[[ "${debug}" = "true" ]] && log_warn "docker network ${network_name} already exists"
return 1
else
return 0
fi
}

function create_docker_network() {
local -r debug="${1:-false}"
local -r network_name="$2"

[[ "${debug}" = "true" ]] && log_info "creating docker network ${network_name}..."

if docker network create "${network_name}"; then
[[ "${debug}" = "true" ]] && log_info "docker network ${network_name} creation completed"
return 0
else
log_error "docker network ${network_name} creation failed"
return 1
fi
}
```

- Look at the create_docker_network function above
- I want to create a network only if it doesnt already exist
- In a normal programming language you would simply return a true or false from the is_existing_docker_network function above
- How do you go about do this kinda thing in bash? Should I actually return 1 if a network exists? Isnt that an error condition?

https://redd.it/1wi0yph
@r_bash

Читать полностью…

r_bash

will someone explain to me getopt?

yes, I am currently reading the documentation - I don't understand the point or when/why I would use it. thanks for any clarification one can offer.

https://redd.it/1wi08yq
@r_bash

Читать полностью…

r_bash

Lbashprofile compare

Hello. Some time ago I added a "compare" subcommand into L\_bash\_profile. I also discovered that with qemu it is possible to count the exact number of instructions executed by a program. Thus now I am able to micro-optimize bash with the number of instructions executed. Below I can share some findings.

How do I use it, I pick two expression to compare given the same input conditions. For example which method is faster to iterate over arguments, is it while (($#)); do ...; shift; done or for i in "$@"? For both expression I define input for example -P 'set -- 1 2 3' will add set -- 1 2 3 to both expression in front and will not count instructions of it. So the following:

$ Lbashprofile compare -m qemu -P 'set -- 1 2 3 4 5 6 6 7 8 9 10' \
'while (($#)); do : "$1"; shift; done' \
'for i in "$@"; do : "$i"; done'
Benchmarking 1/2: 'while (($#)); do : "$1"; shift; done'
Benchmarking 2/2: 'for i in "$@"; do : "$i"; done'
Comparison results (method: QEMU, repeat: 1):
| Code | ExitCode | Insn | ΔInsn |
|--------------------------------------|------------|--------|---------|
| while (($#)); do : "$1"; shift; done | 0 | 251562 | - |
| for i in "$@"; do : "$i"; done | 0 | 167719 | -83843 |

From that I see that for is faster. Usually I write a script with funcitons and do L_bash_profile compare -P '. script' 'func1' 'func2' to compare two functions defined in some temporary script.

Reduce the number of expressions. Literally reduce. You now you can assign variables in one line? Like with local, but no local. Instead of a=1; b=2 you can in one line a=1 b=2 for the same effect. Use arithmetic expansion with side-effects. Instead of a=1; b=2; c=$(( a * b )) you can do (( a = 1, b = 2, c = a * b )).

Fastest way to represent booleans is (( var )) and storing var=1 or var=0. It is faster then storing true or false and doing if $var; then and is faster then [[ $var ]] or [[ $var = true ]] or similar. Overall arithmetic expansion is fast.

Case is fast. Whenever you want to compare strings or want to write [[ string == <glob> || string == <another glob> ]] do a case. Case is optimized, i.e. pattern* will just check prefix, *) will not even compare. You can optimize more, for example instead of if (( bool1 && bool2 )).... elif (( !bool1 && bool2 )) etc. you can do one case "$bool1:$bool2" in 0:0) ... 1:1) ... 1:0) ... etc.

Extglob is slow. Regex is also slow. Glob is fast. Doing string replacements with extglob with big strings is extremely slow. If glob is not enough, use regex, and more often then not one big regex can be used instead of multiple extglob. But overall, use glob whenever you can. One regex is worth more then 10 globs. If you can do something in one regex [[ $var =~ and in about ten globs var=${var##<glob>}; var=${var%%<glob>} var=${var//<pat>/<sub>} use globs. Globs are fast.

For example, to trim leading spaces from a string, using double glob var="${var#"${var%%[![:space:]]*}"}" is twice as fast as var=${var##+([[:space:]])}. That is because extglob is O(n^2) - it tries to match every position in the string going over and over it in a loop.

Do not copy variables. Might sound obvious, but want to mention one thing. It is funny Bash has a "implicit outer scope" of variables, in contrast to other languages. Instead of local args=("$@"); some_function "${args[@]}" refactor and do local global_args=("$@") global_args_index=0; some_function_that_works_with_global_args and just use global_args and global_args_index directly in functions working on one global array. Pushing values into $1 $2 into every function is creating copies and copies everywhere.

Overall, when parsing arguments, shift is slow. Or maybe not shift itself, but the way you build the loop

Читать полностью…

r_bash

Find command confusion between ; and \;

Why do we have to use '\\' instead of leaving it out or even ';'? I read the find commands' manual and it says '\\' might be needed to protect from expansion by the shell. So what is expansion also?

What is difference between \\; or ; or leaving it out?
What is shell expansion here?

https://redd.it/1wifl4l
@r_bash

Читать полностью…

r_bash

I created a modular tycoon in Bash

I created a tycoon in Bash, but it’s not your typical tycoon -it’s modular. That means there’s no upgrading droppers or any of that fluff; instead, you build the droppers yourself using any programming language (or so I assume).

There are two versions of this tycoon on my GitHub: one with a C# module and one without (if the C# module doesn't work quite right, please don't beat me with sticks).

It’s currently in alpha, so there are likely bugs (especially since Bash isn't exactly a language for game development).

If you're curious, give this "quick-and-dirty" coding masterpiece a try - here’s the link to my GitHub: https://github.com/mishkagumiberr-star/modular\_tycoon

Good luck! :)

https://redd.it/1wxkw0n
@r_bash

Читать полностью…

r_bash

bj.sh: a sub-1KB JSON query tool written entirely in Bash

Use jq when you have it. `bj.sh` exists for embedded, restricted, or minimal environments where you have Bash but can’t or don’t want to ship another binary. Paste it directly into a Dockerfile, Ansible playbook, Kickstart config, installer, or provisioning script.

It’s a pure-Bash JSON query tool, under 1 KB in compact form, with no external utilities or runtime dependencies, and a real test suite.

For example:

bj '{"foo":{"bar":["zero","one"]}}' foo bar 1


outputs:

one


It’s intentionally not a jq replacement or a full JSON validator; the goal is simple key/index traversal with as little machinery as possible.

https://github.com/memotype/bj.sh


https://redd.it/1wko18i
@r_bash

Читать полностью…

r_bash

EverythingX: a blazing fast file name search tool for macOS and Linux
/r/freesoftware/comments/1wmr48u/everythingx_a_blazing_fast_file_name_search_tool/

https://redd.it/1wmr4jy
@r_bash

Читать полностью…

r_bash

Not sure if there is a better way to put that along with the debug stuff

https://redd.it/1wn8w07
@r_bash

Читать полностью…

r_bash

Flag ambiguity

I am building a shell framework with a series of commands and subcommands for task-managing, habit-tracking...


Within those, there is a collection of flags that hold different meanings:


- -d Duration, Date...

- -n Name, Note...


- -l Link, Length...


Should I use different letters for different meanings even if they belong to different commands?


I want a real bash-user's opinion, not just the AI's advice.


I personally think that it isn't that big of a deal.



But let me know what y'all think.


Thanks!

https://redd.it/1wo2flm
@r_bash

Читать полностью…

r_bash

Simple digital clock for the terminal

bashclock

I made this simple digital clock for the terminal in Bash as a silly project.

It will show the current time in 24h-format. Use the flag --watch to continuously show the time. A few different looks and colours are available.

To print a bash completion script use --compscript

The repo is here: https://codeberg.org/Linux\_bash\_user153/bashclock

https://redd.it/1wfjor6
@r_bash

Читать полностью…

r_bash

Two ways I tried to clear 268 shellcheck findings from 61 scripts

Two attempts at the same cleanup, on the same 61 scripts. About 7,400 lines of ops and release glue that accumulated in one repo over four years. Baseline was 268 shellcheck findings, counted by running shellcheck across every script and grouping the output by SC code, and roughly two thirds of that was SC2086, unquoted expansion.

The first attempt was mechanical. Read the finding, quote the variable, move on, one script at a time, no restructuring of anything. That closed 231 of the 268 in a single afternoon and touched 54 files. Three places genuinely wanted word splitting, an options string handed to rsync among them, so those got an array instead of a quoted string.

The second attempt was structural. I moved path handling and argument checking into one sourced helpers file and rewrote the twelve scripts that do the most of both against it. That removed about 400 lines and closed 96 findings, but it broke the release path twice in ways shellcheck cannot see, both caught only by running the scripts against a scratch tree, and it cost three evenings rather than one.

I shipped the mechanical pass. Each attempt lived in its own Workspace in verdent, branched off the same commit, so the two diffs sat side by side instead of taking turns in a stash.

The rewrite was better at the thing I did not measure. Those twelve scripts have not picked up a single new finding since, while two scripts written after the mechanical pass landed last month carrying exactly the patterns I had just deleted. If your script count is still growing, the slower approach is probably the right one, and I would not argue against that choice.

https://redd.it/1w8t3du
@r_bash

Читать полностью…

r_bash

Mnemonics for expansion order in Bash

I have long been looking for mnemonics that could help me with the order of expansions/substitutions in Bash. Google returned an "AI overview" with:

Big Tigers Pounce And Catch Wild Prey

where

Big = Brace expansion
Tigers = Tilde expansion
Pounce And Catch = Parameter/Variable, Arithmetic, and Command substitution
Wild = Word splitting
Prey = Pathname expansion/Globbing

which I find quite difficult (but perhaps this is just me).

\--------------------------------------

In any case, here is the mnemonics I have been using:

Bratislava paramedics, comic artists split name quotas

where

BRA.TIsLava = braces, tilde
PARAMEdics = parameters
COMic ARtIsTs = command, arithmetic
SPLIT = word splitting
NAME = pathname/filename
QUOTas = quote removal

From "braces" to "arithmetic", my solution follows the strict sequential order indicated in Newham & Rosenblatt's (2005) Learning the bash shell \[p. 181, O'Reilly\].

As discussed here: [
https://stackoverflow.com/questions/76842556/](https://stackoverflow.com/questions/76842556/), this differs from what `man bash` says:

brace expansion
tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution, done in a left-to-right fashion
word splitting
pathname expansion
quote removal

But I do no think much harm is done, as long one realizes that paramedics and comic artists are on the same plane (which is obvious :).

The advantage of my solution is that phonetics are much richer, and thus easier to connect with the real referents. Plus, Bratislava is a nice place :).

\--------------------------------------

Any comment, opinion, objection, or alternative?

https://redd.it/1w0v2q8
@r_bash

Читать полностью…

r_bash

When do you stop using Bash and switch to Python/JS?

Lately I tried to write a slightly longer Bash script, and honestly, I didn't really enjoy it. I realized I don't understand Bash syntax nearly as well as I thought I did.

Even with AI helping me, I actually want to understand the code I'm writing instead of just having AI fix everything for me.

So I'm curious: Do you still use Bash for longer scripts, or do you have a point where you just switch to another language?



https://redd.it/1vqo9yg
@r_bash

Читать полностью…
Subscribe to a channel