r_bash – Telegram
How to substring a variable using another variable as length?

Hi, I have this piece of code:



length_seq=${#sequence}
fold_without_mfe=${#fold_result:0:$length_seq}

​

Where length_seq is the length of a genomic sequence, for example, 30. The fold_without_mfe variable is a simulation result, but it has a few more characters than I need, so I want to take only the firt 30 of this variable to match my sequence. I tried this but it throws me a bad substitution error, how can I approach this problem?

https://redd.it/14xlrwr
@r_bash
How can I get just part of the line in my text file?

I am running this command, trying to gather some data

grep -e "PROJECT" $(sudo find /path/to/dir/ -iname config) > projects.txt

and get a lot of output like this:

/path/to/dir/config/config-server.address:PROJECT="xyz";

All i want is the information between : and ;

I have tried using awk, but this gives me the same as no awk

grep -e "PROJECT" $(sudo find /path/to/dir/ -iname config | awk '{print $1}') > projects.txt

​

https://redd.it/14xriut
@r_bash
Bash grievances

At this moment I have a love/hate relationship with Bash. I write in it for years and I can say that I write it, with modesty, well.

I understand that Bash isn’t like modern programming language like Golang.

But from time to time when I want to refractor code or more structured setup I felt more and more that the language is in the way.

Trying to translate something like the composite design pattern to Bash was not possible because it is so simple as it can be. That it doesn’t have support like inheritance. Return a type from a function and not by declaring or print it. Passing a function as a argument to a function is not possible.

All the things that could make life/noscripting a little bit easier, it doesn’t have any support for it.

And Bash has made progress in the last ten years. Arrays is something that I frequently use. But the speed of developments is way too irritating slow. Just as the speed of the shell it’s self.

And yes. I acknowledge the existence Python and others. But as someone who comes to different companies where there is no knowledge of these modern languages (even in 2023), I have to do it with Bash.

https://redd.it/14xwui5
@r_bash
How can I find files from a list without the extension?

I'm working on a personal project. I have 2 folders:


/JPG
/RAW


Each folder should contain files with identical filenames but with different extensions (they will always be either .jpg or .rw2)


For example:

/JPG/image1.jpg
/JPG/image2.jpg
/RAW/image1.rw2
/RAW/image2.rw2


Now there are some instances where a file only exists in one folder, but not the other.


I have identified these files and placed them into a list within a .txt file using the below command:

comm -3 <(print -lr JPG/*(:t:r)) <(print -lr RAW/*(:t:r)) > differences.txt


When I cat this file, I can see all the files which only belong to one of the folders. For example:

cat differences.txt
image7
image36
image49

&#x200B;

My next goal is to move these files into a new folder. But I'm not sure how. As you can see, the extensions were removed/excluded when they were outputted to "difference.txt"

I was thinking maybe I should use the find command and input a list but that doesn't seem to be possible. I've tried a few noscripts I found on stack overflow but to no avail.

Please could somebody point me in the right direction?

https://redd.it/14y0v6i
@r_bash
Need help with a one-liner for renaming files.

I have folders of files that start with a year, but need the year on the end in parentheses.

main/folder1/1999 - file1.txt
main/folder2/2000 - file02.log

rename to:

main/folder1/file1 (1999).txt
main/folder2/file02 (2000).log

I don't know enough to knock this out quickly, anybody give me a hand?

Obviously doesn't need to be a one-liner, just seems like it should be pretty simple with the right knowledge.

https://redd.it/14yjick
@r_bash
Searching for multiple strings within a list

Hello - I have the following noscript



>\# Get list of images with specified tag for downloading
tags=$(aws ecr --region ${SOURCE_REGION} list-images --registry-id ${SOURCE_AWS_ACCOUNT_ID} --repository-name ${REPOSITORY_NAME} | jq -r 'map(.[\] | .imageTag) | join(" ")')
list=$(for tag in $tags; do
if [[ $tag == "release"* \]\]; then
echo "$tag"
fi
done)

is it possible to add more filters and add them to the $tag variable? So what if I had something like

> if [[ $tag == "release"* \]\] && [[ $tag == "testing"* \]\] ; then

basically, I'm trying to match and extract multiple strings from a list and then pass those filtered results further down the noscript. Help much appreciated!

https://redd.it/14yna3b
@r_bash
How does bash, and other shells, figure out the correct environment variables?

If I use the env command I see that bash and zsh both have figured out the correct TERM, HOME, LANG and XDG... variables. Where does the shell look to find the value of this variables?

https://redd.it/14zbo8z
@r_bash
C++ Build Error Handling

Hi, I wrote a .sh that catches an error if the make command fail, but it happens only when the make execution ends. So I just look at the return. I was wondering if it is possible to catch error during the compilation time. I hope to be clear

https://redd.it/14zpptp
@r_bash
su into account, from root, and get password prompt

Realize this is a weird situation, but far as I can tell, this is the only way out of the problem.

Alright, I have an extremely odd situation. I need to su to a user account but have it ask for the password, and I need to do it from root. lol.

So what I found was, I can be root, su to the user account (no password prompt), then I can su from the user into itself, and a password is prompted.

I tried something like

sudo -u account echo "password" | sudo -S -u account echo ""

but it didn't seem to work. it appears I can't just sudo, I have to actually su.

So I'm wondering if I can use expect, but it's not working either (likely my ignorance as to how expect works)

As root:

sudo -u account expect -c 'spawn su account;expect Password:;send "sekritPassword\\n";send "whoami\\n";send "exit\\n"'

Doesn't seem to do what I would _expect_. Har har.

Anyone think of a way to do this?

https://redd.it/14zsqp8
@r_bash
Why printf over echo? (noob question)

I regularly come across comments in which it's recommended to rather use printf than echo in shell noscripts. I wonder why that is.
And in this regard: would it be worth the time and energy to replace all the echos in a working noscript with printf?
And last question: do people usually get annoyed when you use both, echo and printf in one noscripts (a published noscript that is)?

https://redd.it/1519wby
@r_bash
Pinging periodically using a noscript and crabtab

In the past week or so my home internet feels unstable. So I created the following little noscript to check it out:

'''bash
#!/bin/bash

# Change the destination log file path
log_file=~/Code/PingsLogger/pings.log

# Replace 'your_router_ip' with the IP address of your router or the server you want to ping
router_ip='8.8.8.8'

# Ping the router and record the result to the log file
ping_result=$(ping -c 1 $router_ip | grep 'bytes from' | cut -d '=' -f 4)
current_time=$(date +"%Y-%m-%d %H:%M:%S")

if [ -n "$ping_result" ]; then
echo "$current_time - Lag: $ping_result ms" >> $log_file
else
echo "$current_time - Request timed out" >> $log_file
fi
'''

Saved it to a file named [pings.sh](https://pings.sh) (called chmd and such), initiated a file name pings.log and I added to crontab the following line:
`* * * * * ~/Code/PingsLogger/pings.sh`

When I run the noscript manually it does the job and adds a new line to the log but when the crontab runs it it always adds only 'Request timed out' to the log file.


Can someone help me understand what am I doing wrong? :(


https://redd.it/152sx45
@r_bash
My personal trick to improve "test" command readability

I know it may not be a problem for bash noscript veterans, but for someone like me who write bash noscripts not quite often, bash test operators are too concise to be memorized long term or read. As of writing, I only remember for certain simple ones like "-e" for "file exists", "-f" for "file is regular file", "-d" for "file is directory". I remember several times I mistook "-n" for "file not exists", however in fact, there is no test operator for "file not exists". If I need to write some bash noscript after one week or two since I last wrote some bash noscripts, I certainly have to check 'man test' again because

1. I forget what some operators represents
2. I remember what some operators represents, but at this time I'm not sure I remember it right
This scenario has occurred several times on me, and it is annoying.

The other problem is about readability. Bash's conciseness is good for commandlining, but not for readability. Whenever I encounter a test operator, there is a mapping process in my brain to map the letter to the function it performs. Some mapping may be quick, like "-d" for "is directory" since "d" is the first letter of "directory", but some are not, like "s" for "file is not zero size". I think they just randomly picked a remaining letter for this. Whether quick or not, there is this extra mapping going on. And this is annoying. If I'm using some other object-oriented programming language, there must be some function like isDirectory(). And this is straightforward, no extra mental mapping.

So I use a simple trick to help me.
If I'm gonna use a test operator, I use a variable with a denoscriptive name to replace it.
For example, instead of

if test -h '/etc/somefile'; then
echo it is a symlink
fi

I use this

fileissymlink='-h'

if test $fileissymlink '/etc/somefile'; then
echo it is a symlink
fi

This is more readable and fewer magic letters!
This depends on personal preferences. Some may not like this verbosity, but I do.

In order to keep consistency within all my bash noscripts. I have to create definitions for all operators that need to be replaced. like this
> fileisexecutable='-x'

> stringisnotempty='-n'

> file
issymlink='-h'

> ...


Now, in all my bash noscripts, I include the needed definitions in the file.
For some operators, like "-eq", "-gt" and so on, as they are denoscriptive enough, I just use them.

But there is so much extra typing! Luckily, many text editors today can be extended to suit personal needs.
I use emacs. First I added extra code completions. Now when I type "$fi", a popup completion list shows all the candidates I have defined, like:
> file
issymlink

> file
isexecutable

> file
exists

> fileispipe

> fileissocket

> fileisreadable

> fileisterminal

> ...

I just choose what I need.

Second, I don't want to manually type the definitions. I created a function to automatically run before save the bash file. It will search my bash noscript. If it found one, it will add the definition after the shebang.

Great. If now I want to write a if statement to test whether a file is connected to a terminal.
I just type if test $fi, select "fileisterminal" from completion list, finish the if statement, save the file. file_is_terminal='-t' is automatically added after shebang. I don't need to care about choosing the right magic letter anymore, and it is so readable.

The readability is only applied to noscripts written by myself. If I'm going to read others' bash noscripts, I'm pretty sure I have to face the magic letters again. Luckily, I don't quite often read others' bash noscripts.

https://redd.it/152uw68
@r_bash
Bash command error

Hi, I don't know bash at all, and GPT4 was unable to help...
I'm trying to run this bash command:
`sed -i .tmp -E 's/"(version)"[ ]*:[ ]*".*"/"\1": "1.8.4"' bower.json`
and getting this error:
`sed: -e expression #1, char 1: unknown command: \`.'`


Any idea?

https://redd.it/152x6lg
@r_bash
I could use some help with automation for git pull and passing username and password

Hi,

I would like to automate an update of my dot files repo and since git keeps credentials in plain text, I would like to avoid that and pass the username and password each time (credentials will be retrieved from keepassxc)

I cannot figure out, how to feed credentials to the git prompt, here is my test noscript (please forget about the keepassxc part for now):

#!/bin/bash

user="user"
pass="abc123"

echo "DEBUG user: $user"
echo "DEBUG pass: $pass"

cd ./tst2/tst
(echo $user; echo $pass) | git pull

It doesn't work, git still waits for me to pass the username. I don't understand why, because I've used the same structure (echo $var1; echo $var2 ...) | <command> in different examples, like automation of drives partitioning with fdisk, and it worked just fine.

https://redd.it/1536qwd
@r_bash
syntax for hash comparisons. newbie help

what is the code/syntax to compare:

i have a string. i want to hash it and compare that hash to a hash stored in a file

something like:

if [ "string" | sha256sum -eq cat file.txt \] ; then

&#x200B;

https://redd.it/153hs6y
@r_bash