r_bash – Telegram
How does cat cat << EOF exactly work?

Can someone dissect in great details what's exactly going on when you run that cat command with cat << EOF?


cat << EOF > file.txt


Or when you write a noscript and then output text via writing:


cat << EOF
------
Some text to display when this noscript is run
------
EOF


I have a vague idea of what's going on but I'd rather a shell guru explains it correctly, just so I don't assume things.


I know that EOF stands for End of File and that it's just a convention, I could use abc instead and it'd still work.


What happens here is that cat << EOF lets you redirect inputs to cat until you type EOF to quit. cat will then output to the display what you just typed.


So cat << EOF > file.txt redirects everything you type to cat until the keyword you provided (EOF in our case) was entered, and when that happens, cat's output is redirected to be written to file.txt.

When EOF is entered, the shell? (or cat?) somehow knows the end of file is reached, and doesn't continue writing input to cat, how does that "magically" work? Is EOF detected by the shell interpreter or the cat command?



I get the general idea that cat << EOF tells the shell to give cat every line that follows, until the EOF is encountered again, I know what the lines do, I just don't understand the logic behind it. Does the redirection syntax signal to the shell that we only want cat to display whatever values of text that are only between the first EOF and the last EOF?

https://redd.it/132dgu9
@r_bash
How can I configure my bashrc so that the man command always check the number of columns available before re-rendering the text after I maximized the terminal window?

I have the following annoying pattern. I have the terminal emulator set to open at a certain geometry. When I open a man page, it's hard to read this way, so I maximize the window. The problem is the window background is max, but the text is still rendered as if it is limited to half the screen. Instead of using 211 cols, it still uses 86.

https://imgur.com/kMGIUSB

I tried some ChatGPT, but I failed. I guess I don't know how to ask. It told me to export MANPAGER='less -r' and source it. That didn't work. I asked a bit more and told me to try trap 'COLUMNS=$(tput cols)' SIGWINCH Still does not work for me.

So as of now I do it manually (q to exit less, arrow key up and voilà the text is rendered out with 211 columns). I tried to change the man pager to most. Same story. I tried different terminal. The same. I see nvim or nano don't have this problem. The column size gets recalculated when the window is maximized, neither less by itself. For example, less /var/log/syslog the text gets rendered taking into account the column size when I toggle between maximized and unmaximized.

Also, worth saying with man the problem doesn't happen if the terminal is maximized when initially opening the page, I can toggle the terminal window size and the text gets re-rendered just fine. It only has an issue when I try to increase the size of the window and for whatever reason the variable that holds the size of the available columns doesn't get pass.

Any help?

https://redd.it/132nrry
@r_bash
Mainline Nginx for Amazon Linux 2023

I am unable to install nginx from nginx repo instead it is installing nginx from amazonlinux repo again and again after following this [instructions\](http://nginx.org/en/linux\_packages.html#Amazon-Linux:\~:text=To%20set%20up%20the%20yum%20repository%20for%20Amazon%20Linux%202023%2C%20create%20the%20file%20named%20/etc/yum.repos.d/nginx.repo%20with) :

So, after failing i did

`dnf config-manager --add-repo http://nginx.org/packages/mainline/amzn/2023/`

'yum install nginx -y`

and came up with this error

```

nginx mainline repo 21 kB/s | 8.1 kB 00:00

created by dnf config-manager from http://nginx.org/packages/mainline/amzn/2023/7.1 kB/s | 3.3 kB 00:00

Errors during downloading metadata for repository 'nginx.org_packages_mainline_amzn_2023_':

\- Status code: 404 for http://nginx.org/packages/mainline/amzn/2023/repodata/repomd.xml (IP: 3.125.197.172)

Error: Failed to download metadata for repo 'nginx.org_packages_mainline_amzn_2023_': Cannot download repomd.xml: Cannot download repodata/repomd.xml: All mirrors were tried

Ignoring repositories: nginx.org_packages_mainline_amzn_2023_

Dependencies resolved.

```

&#x200B;

https://preview.redd.it/7luxns5uatwa1.png?width=1899&format=png&auto=webp&v=enabled&s=ae9968d26e7691602c24fa3e482a4aa6ad9b175c

there should be nginx-mainline in the first row of repository.

How do i resolve this i can't understand .

https://redd.it/132qu2r
@r_bash
Best courses to learn bash noscripting

I want to learn bash noscripting. I know there are lot of resources out there but i want a course or site where they give small tasks or assignments along with the video.
I want to learn end to end. Like using awk,sed etc

https://redd.it/132sd5a
@r_bash
Why aren't my aliased commands registering when ran with sudo?

And yes, I have "alias sudo='sudo '" in both my "~/.bashrc" and "/etc/bashrc" files along with the rest of my aliases.

I use fish (with the same aliases in "~/.config/fish/config.fish") too, but there's the same problem whether I'm using the commands with sudo in both fish and bash.

https://redd.it/132phhm
@r_bash
Why does > /dev/null 2>&1 work while > /dev/null 2>>&1 doesn't?

Assume abcd is a file that doesn't exist.


Why does redirecting stdrr to stdout file denoscriptor via using the single overwrite operator works as expected:


cat abcd > /dev/null 2>&1


While using the double redirection operator for appending doesn't?



cat abcd > /dev/null 2>>&1




I'm on bash 3.2 that comes shipped with macOS if anyone's wondering.

https://redd.it/132yqr3
@r_bash
Improvement in my "=" alias which bookmarks directories and creates shortcuts

I've made an improvement in my favorite bash alias (actually a function) that I use it to navigate all over the filesystem, bookmark where I am, go back, and move files around.

The alias "=" remembers, or bookmarks your current directory.

Usage examples:

% = A # bookmark current directory as "A"
% A # go to directory bookmarked as A
% cp file $A # copy file to bookmarked directory
% cp file "$A" # as above, but if the directory contains spaces, etc.
% cp $A/file $B # copy file between 2 bookmarked directories when you are in
# a third directory, etc.

Add this to your \~/.bash_aliases file and then type ". \~/.bash_aliases"

function = () { # remember current directory using "= varname"
# and create alias/function that changes directory
# by grymoire - 4/30/2023
eval "$1"='$(pwd)'
eval function "$1" "() { cd \"\$$1\" ; }"
}


Example of usage:

me@cpu:~/$ cd ~/Downloads/ # go to my downloads directory
me@cpu:~/Downloads$ = D # bookmark it as "D" for Downloads
me@cpu:~/Downloads$ cd /media/me/FLIPPER\ SD/ # switch toi my flipper directory
me@cpu:/media/me/FLIPPER SD$ = F # bookmark it as "F" for flipper
me@cpu:/media/me/FLIPPER SD$ D # go back to my Downloads directory
me@cpu:~/Downloads$ cp file.tar $F # copy file to my flipper directory
cp: target 'SD' is not a directory # oops. Forgot - a space in name
me@cpu:~/Downloads$ cp file.tar "$F" # do it the right way
me@cpu:~/Downloads$ F # jump back to my flipper directory
me@cpu:/media/me/FLIPPER SD$ rm file.tar # move/delete the file
rm: remove regular empty file 'file.tar'? y
me@cpu:/media/me/FLIPPER SD$ D # go back to my downloads directory
me@cpu:~/Downloads$



I find this much easier to use than the pushd/popd commands. This is also the first time I had a function, that when called, defines a new function. Cool!

I often download files and copy them into my \~/Git directory, and this makes it easy to navigate and copy files all over the filesystem. Hope you like it.

https://redd.it/133tyzt
@r_bash
"Immortal" Bash noscripts, using inline Nix and a special header block

I've been learning Nix and as an application for a job (yes, still looking for work) I wrote a single-file Bash app that provided a TUI to look up food truck eateries (downloaded and cached from an online source CSV) based on a filter and sort by distance from you. To make this work I needed to rely on a few external binaries- the right versions of bash, GNU awk, jq, curl, csvquote and this neat thing called `gum`. I finished it but in the course of testing it I realized that I got it running fine on Linux (NixOS) but it acted a bit wonky on macOS (and since I was actually applying for a primarily Elixir-lang job, I knew most devs would be on Macs). And the reason it was wonky was due to a version difference in both Bash and Awk. At that point I decided to go for my "stretch goal" of getting everything and all necessary dependencies optionally bootstrapped via Nix so that, assuming one had Nix installed and an Internet connection, the noscript would be "guaranteed" to run for the foreseeable future and would automatically (!!!) download (or read from cache), install, and make available the right dependencies AND re-run the noscript with the right version of Bash.

I succeeded in this task =) thanks to /u/Aidenn0 and this thread (which actually had other solutions to this problem, but I liked this one because I could include it all in the same file).

So now, not only does it fall back to some basic dependency checking if you don't have Nix installed (or you source the file instead of running it directly), not only does it know how to find and install any needed dependencies if you DO have nix installed, not only does it run all this in a "pure" environment that is constructed on-the-fly, not only does it actually re-run itself with the right Bash version (which is why it starts with sh, actually, in case you don't even have Bash installed!), it also has a (pretty basic) test suite, AND test data, all in the same file.

Accomplishing all this in 1 file was a bit complex (code golfing? Yeah, kinda, maybe), so I tried to comment heavily. (For any other explanations, you could ask ChatGPT, which was actually very helpful to me as well!)

Here is the gist. The "magic Nix" section is the "DEPENDENCY MANAGEMENT" section. You'd have to adapt this to your use-case (such as whitelisting the correct env vars and specifying the right dependencies), but maybe there are some ideas in here you can use in your own noscripting projects. I'm sure many of you have encountered the situation where a noscript you relied on stopped working all of a sudden because of a change to something it depended on...

Negatives? Well, the first time you run the noscript, there's a multi second delay as it gets and caches all the deps into the "Nix store" (very cool to watch though!), and any further time you run it there's a small (sub-second) delay as it verifies all the specified deps are still available in cache (cache TTL depends on your Nix config). That's only if you have Nix installed. (Maybe I could add an env option to SKIP_NIX if you are sure your existing session already has all the right deps available.)

Thoughts? Suggestions?

https://redd.it/133w2sh
@r_bash
Question for the Greybeards - How to redirect permission Denied to an Error File

Have file a SomeFile.txt where owner is root.

want to do something like echo "Text" >> SomeFile.txt 2> error.log

My goal is to get the resulting permission denied into the error.log, but this does not work and the error is printed to the terminal.

Note that I'm purposely running as a regular user as I'm focused on the output redirection atm.

Not a school assignment, but saw sometthing like this in another reddit, and it got me wondering how to accomplish this.

Any Ideas? Suggestions or help is greatly appreciated.

https://redd.it/1343i2i
@r_bash
My noscript works but why?

Hello there;

So I have this txt file that contains 300 something links to free (as in free of charge not pirated) JS tutorials from a course in my language.
The site that offers the course suggested that students should drop the links one by one into IDM, but I thought to hell with that! We are smarter than that aren't we? :)

So I wrote a quick noscript like this:
dl_list=$(cat ~/downloadlist.txt)

for i in $dl_list; do
wget $i
done

and it worked. all the links in that txt file were downloaded with no problem.
But I have a question now. why did it work when I didn't use the correct array syntax?
shouldn't I have done something like this?
dl_list=$(cat ~/downloadlist.txt)

IFS=$'\n' read -d '' -r -a LINKS < "$dl_list"

for link in "${LINKS[@]}"
do
wget "$link"
done


is it something about wget that made it work or am I missing something about bash?

https://redd.it/1346wl8
@r_bash
Question! Why Double quota array can avoid re-splitting element




# I have array
arrayvar[0]="test 1"
array
var1="test 2"
arrayvar[2]="test 3"
array
var3="test 4"
arrayvar[4]="test 5"
array
var5="test 6"
# and I have two for loop:
for ele in ${arrayvar[@]}
do
echo "$ele"
done
for ele in "${array
var@}"
do
echo "$ele"
done

in the first for loop, I know It's will print

test

1

test

2

test

3

test

4

test

5

test

6

&#x200B;

but I am confused why the second loop can work perfectly

because if we add ${array_var[@\]} a quote, which I think should be "test 1 test 2 test 3 test 4 test 5 test 6", there will only be a round loop because we double quoted it.

Could you tell me what Bash does for array?

https://redd.it/134fbgh
@r_bash
shell noscript in crontab only work if run with sudo , when run noscript with sudo it show less output

I have noscript to check ssh connection quality to servers, when I put this noscript in crontab, it work only with sudo , for example when I run

sudo crontab -e

this is my noscript

#!/bin/bash
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
PATH=/bin:/usr/bin:/sbin
# Define the remote servers and output files
servers=( "1.2.3.4" "1.2.3.5" )
output_files=( "server1_output.txt" "server2_output.txt" )

# Define the user to connect as
user="admin"

# Loop over the servers
for i in "${!servers[@]}"
do
server="${servers[$i]}"
output_file="${output_files[$i]}"

# Test the SSH connection quality
ssh_start_time=$(date +%s.%N)
ssh_quality=$(ssh -q -o BatchMode=yes -o ConnectTimeout=5 "$user@$server" "echo SSH quality test successful." 2>&1)
ssh_end_time=$(date +%s.%N)
ssh_time=$(echo "$ssh_end_time - $ssh_start_time" | bc)

# Check the SSH connection quality
if echo "$ssh_quality" | grep -q "successful"; then
echo "SSH quality to $server is good. SSH time: $ssh_time seconds." >> "$output_file"

# Run the ls command and write output to file
ssh -q "$user@$server" "ls -la" >> "$output_file"
else
echo "SSH quality to $server is poor." >> "$output_file"
fi

# Close the SSH connection
ssh -q -O exit "$user@$server"
done

another problem is this when I run this noscript with sudo command it show only SSH quality and when run it without sudo it show more output like ls -la too

&#x200B;

I use Manjaro and cronie package installed too.

https://redd.it/135dik6
@r_bash
No redirect to variable?

There is probably a reason this is not a thing but it seems useful.

You can redirect stdin from text/a variable:

cmd <<< text

but it seems logical to implement something like the following for simple and flexible output redirection to variables:

cmd 1>>>var1 2>>>var2

Has this already been considered?

The best solution I have to capturing output this flexibly is this monster cobbled together / copied from stackoverflow:


catch() {
{
IFS=$'\n' read -r -d '' "${1}";
IFS=$'\n' read -r -d '' "${2}";
(IFS=$'\n' read -r -d '' ERRNO; return ${ERRNO});
} < <((printf '\0%s\0%d\0' "$(((({ ${3}; echo "${?}" 1>&3-; } | tr -d '\0' 1>&4-) 4>&2- 2>&1- | tr -d '\0' 1>&4-) 3>&1- | exit "$(cat)") 4>&1-)" "${?}" 1>&2) 2>&1)
}

catch MYSTDOUT MYSTDERR './useless.sh'
echo "exit: ${?} stdout: ${MYSTDOUT} ${MYSTDERR}"

https://redd.it/135mdqt
@r_bash
how do i write stuff to a line in a file?

so i am making a noscript that sets a wallpaper and color scheme and i want it to replace the color scheme i have set in my .bashrc for the one i picked in the program how would i do so?

https://redd.it/135n7qt
@r_bash
Loop only executes on first Line

while IFS="=" read -r filename url; do
if [ ! -f "$folder/$filename" ]; then
echo "Downloading $filename from $url..."
wget -O "$folder/$filename" "$url"
echo "Download complete."
else
echo "The file $filename already exists in $folder. Skipping download."
fi
done < "$noscript_folder/urls.txt"

This is supposed to work on a File like:

name=url
name=url

but it seems to only be running on the first line.

What am i doing wrong ?

https://redd.it/135td5q
@r_bash
Help with using mktemp files and gnuplot

Please could someone help me with using gnuplot. I am just trying to practise the basics but wanted to use mktemp instead of the .csv file (which the noscript does work with).

This is my noscript:

#!/bin/bash

# Define the input and output files
datafile=$(mktemp)
cat data.csv > $datafile

head $datafile
echo ""
echo ""
echo "Using data file: '$datafile'"
echo ""

# Use Gnuplot to create a graph
gnuplot -e "set terminal pngcairo; set datafile separator ','; set output 'output.png'; plot '$datafile' using 1:2 with lines"

echo ""
echo "Using data file: '$datafile'"

rm $datafile

This is the output:

1,5
2,3
3,2
4,7
5,4

Using data file: '/tmp/tmp.KmYFhmSjTl'

line 0: warning: Cannot find or open file "/tmp/tmp.KmYFhmSjTl"
line 0: No data in plot


Using data file: '/tmp/tmp.KmYFhmSjTl'


The mktemp file seems to be there both before and after the gnuplot is used so I am confused.

If it matters I am using cygwin on Windows.

Thanks for your help in advance!

https://redd.it/135uyro
@r_bash
Explain the Bash reference entries about `$@' and `$*'

I'm struggling with understanding the language of the following denoscriptions of these two parameters.

`$@`

>Expands to the positional parameters, starting from one. In contexts where word splitting is performed, this expands each positional parameter to a separate word; if not within double quotes, these words are subject to word splitting. In contexts where word splitting is not performed, this expands to a single word with each positional parameter separated by a space. When the expansion occurs within double quotes, and word splitting is performed, each parameter expands to a separate word. That is, "$@" is equivalent to "$1" "$2" …. If the double-quoted expansion occurs within a word, the expansion of the first parameter is joined with the beginning part of the original word, and the expansion of the last parameter is joined with the last part of the original word.

`$*`

>Expands to the positional parameters, starting from one. When the expansion is not within double quotes, each positional parameter expands to a separate word. In contexts where it is performed, those words are subject to further word splitting and pathname expansion. When the expansion occurs within double quotes, it expands to a single word with the value of each parameter separated by the first character of the IFS special variable. That is, "$*" is equivalent to "$1c$2c…", where c is the first character of the value of the IFS variable.

1. "each positional parameter expands to a separate word": what is a **word**?
1.1 Is the sentence saying that each parameter is a word or a list of words?

2. "if not within double quotes, these words are subject to word splitting": are these words the ones that came up as the result of the parameter expansion?

3. "this expands to a single word with each positional parameter separated by a space": is this word a part of the positional parameter or preceding the list of the parameters? Could you illustrate this situation?

4. "If the double-quoted expansion occurs within a word, the expansion of the first parameter is joined with the beginning part of the original word, and the expansion of the last parameter is joined with the last part of the original word. ": this is the spot I'm tripping over particularly as I'm having a hard time trying to visualize the scenario. What is "double-quoted expansion within a word" and how does it superimpose on this expansion? Could you give an example?

5. "it expands to a single word with the value of each parameter": what is a single word? What does the expansion look like? The situation is similar to the one referenced in #3.

https://redd.it/1360x8a
@r_bash
Join me



1. I'm working on a new project for WordPress websites that checks which plugins are causing 500 error and turns them off https://github.com/Noam-Alum/wp\_plugins\_checker if someone wants to join me send me DM, an extra pair of hands would be helpful (Note that the project is purely a backend tool since the website is not working... and I wrote it in bash noscripting )
2. feel free to try it and add to the issues tab on github

https://redd.it/136lbxj
@r_bash
Help me understand the possibilities of Bash (best uses, etc)

Little about me and why I'm posting.

Currently studying cyber security and taking a Linux class which is diving a little bit into bash. I have nearly a decade of experience messing with different programming and noscripting languages, mostly from experimenting with web design, game development and some software development, all on a hobbyist level.

I've picked up Bash really fast (obviously by no means on the level of the rest of this subreddit), but my class is coming to an end and I want to see if it's worth continuing learning bash in my free time. It's simple enough understanding the syntax, and I can see some cool tools that I could make with it, but what are the major uses and reasons I should stick with it?

I see things about using Bash for automation, I could see that being useful. I saw a post in this sub about someone writing some back-end code for a web project in bash? Is there any application of this language that could be used for anything GUI oriented? I think of bash as all command line/terminal dirty-work.

Just looking to gain some knowledge on the possibilities of Bash.

TL;DR: College student learning bash, is it worth continuing to learn after my class is over, and what are the best uses for bash noscripting?

https://redd.it/136rgkx
@r_bash