Linux.org User-created Helpful Shell Scripts

RECOMMENDATION: A Reference Book for C Programmers

I have written a few lines of C code and would like to share a helpful book. I like to have it nearby when programming in C. I bought two copies - one at work and one at home (or sometimes in my laptop case).

C: A Reference Manual
Samuel P. Harbison III, Guy L. Steele Jr.
ISBN 0-13-089592-X (from the back of my copy)
Amazon's listing:
ISBN-10 ‏ : ‎ 9780130895929
ISBN-13 ‏ : ‎ 978-0130895929

The selling price at Amazon is way too high. Find a used copy for a reasonable price.

This is NOT a cover-to-cover read for people to learn C. It is a reference book for people who know enough C to write code, but need to look up the subtle behaviors of C language constructs. This book documents exactly how the C compiler behaves in every possible situation, including the pre-processor and all those weird corner cases. I said "every possible situation" and still "assert" that it is true - I never found anything in C that was not covered by this book.
I actually just bought a used version for $8, you have to click on the listing to find the lower prices...

I'll take your word for it that it's good, i haven't bought a paperback coding book in a while...however, those c languages haven't really changed much, so it shouldn't be a problem. Just new standards added, C11 is the latest.
 


I mean in your copy of the Firefox.desktop file, edit the Exec=/path/to/firefox field to amend the website address.
E.g.
Code:
Exec=/path/to/firefox https://www.timeanddate.com/timer/

However, your Firefox is using snapd, ugh! So I don’t know offhand if this approach will work or not. You could give it a go though. It should work.

And if it doesn’t, you can add yet another item to the list of reasons why snapcraft/snapd completely sucks!
No lol, you can't change that file at all even as the root user. There is some way to change the file, but there's something complex with the permissions...like, only a specific "owner" (which in reality is the AI inside of firefox install/environment) can make the changes.

I kinda would like to experiment with the non-ubuntu flavors of linux, but not if it means i have re-install everything again.
 
I mean in your copy of the Firefox.desktop file, edit the Exec=/path/to/firefox field to amend the website address.
E.g.
Code:
Exec=/path/to/firefox https://www.timeanddate.com/timer/

However, your Firefox is using snapd, ugh! So I don’t know offhand if this approach will work or not. You could give it a go though. It should work.

And if it doesn’t, you can add yet another item to the list of reasons why snapcraft/snapd completely sucks!
Disregard my last post about permissions, i've requested for it to be deleted because that was my error in what i was doing

no it doesn't work when i try running it as a script by itself (you have to make it executable...), i feel that it has something to do with me not knowing how to activate symbolic links.
 
Disregard my last post about permissions, i've requested for it to be deleted because that was my error in what i was doing

no it doesn't work when i try running it as a script by itself (you have to make it executable...), i feel that it has something to do with me not knowing how to activate symbolic links.
None of my posts on that particular topic mentioned using a script.
1. Copy the firefox.desktop file from wherever it currently is to ~/.local/share/applications and rename it to online-timer.desktop, or something similar.
e.g.
Bash:
cp /path/to/firefox.desktop ~/.local/share/applications/online-timer.desktop
It doesn't matter if the file is owned by root, copy it as a normal user and you should still be able to copy the file to somewhere in your home directory and the copy will be owned by you. You may or may not need to make it executable, IDK offhand.

2. Edit the Exec=/path/to/firefox field in the copied and renamed .desktop file, to add the URL to the website.
e.g.
Bash:
Exec=/path/to/firefox https://www.dateandtime.com/timer

And then, optionally - create a symbolic link on your desktop, that points to the .desktop file.
Bash:
ln -s -T ~/.local/share/applications/online-timer.desktop ~/Desktop/online-timer
And that is literally it.

Oh, one thing I forgot to mention is to change display name of the program in the desktop too.
So, for that - open up the copied .desktop file and edit the Name and Comment fields in the file too.
Because the name in that field will still be "Firefox" and the description will be "Browse the web".

So perhaps change the name to "online-timer" and the comment to "Open online timer website in Firefox".
Otherwise, you'll just end up with two shortcuts in your menu that say Firefox! :/


For the sake of completeness - I've ran through the steps myself. So I've just installed LXDE, so I have an actual desktop with a GUI Menu system. I don't plan to use the timer application, but I come here a lot.
So I'll set up a shortcut to Linux.org instead of the timer website that @CrazedNerd originally referenced.

On my Debian installation, my firefox.desktop is actually located at /usr/share/applications/firefox-esr.desktop.
So I've copied that fie to ~/.local/share/applications and renamed it to linuxorg.desktop.
I've edited the Name= and Comment= fields to read:
Name="linux.org"
Comment=Open linux.org in FF-ESR

I've opened up the system menu in LXDE and I can immediately see my linux.org .desktop launcher in the menu. Clicking on it opens Firefox to Linux.org.
Great success!
For proof, here's a screenshot:
2023-03-18@19-20-24_1366x768.png


So that works perfectly.
The next step is to set up a symbolic-link in the desktop directory.
Bash:
ln -s -T ~/.local/share/applications/linuxorg.desktop ~/Desktop/Linux.org

LXDE doesn't seem to show the Desktop icons on the actual desktop, but opening PCManFM, I can see that the link is there.
Proof:
2023-03-18@19-39-48_1366x768.png


And clicking on it does work, but you get a prompt about it being an executable script and gives you options to execute it, execute in terminal, open it (which opens it in your text editor), or cancel.
Selecting execute opens the browser to linux.org. So the shortcut to the desktop file works.
Screenshot below:
2023-03-18@19-44-39_1366x768.png

There's no need to mess with any file-permissions.
It works pretty much exactly as described.

I'm going to log out and log back into dwm now. Using LXDE is annoying me now. The workflow just feels jarring and horrible compared to dwm! Ugh, I feel dirty now! Ha ha!
 
I actually just bought a used version for $8, you have to click on the listing to find the lower prices...

I'll take your word for it that it's good, i haven't bought a paperback coding book in a while...however, those c languages haven't really changed much, so it shouldn't be a problem. Just new standards added, C11 is the latest.
$8 is a good value for sure. Keep in mind that it is not a cover-to-cover spellbinder. It is more like having a dictionary next to you while you write. The more you code in C, the more you will appreciate having that book next to you.
 
None of my posts on that particular topic mentioned using a script.
1. Copy the firefox.desktop file from wherever it currently is to ~/.local/share/applications and rename it to online-timer.desktop, or something similar.
e.g.
Bash:
cp /path/to/firefox.desktop ~/.local/share/applications/online-timer.desktop
It doesn't matter if the file is owned by root, copy it as a normal user and you should still be able to copy the file to somewhere in your home directory and the copy will be owned by you. You may or may not need to make it executable, IDK offhand.

2. Edit the Exec=/path/to/firefox field in the copied and renamed .desktop file, to add the URL to the website.
e.g.
Bash:
Exec=/path/to/firefox https://www.dateandtime.com/timer

And then, optionally - create a symbolic link on your desktop, that points to the .desktop file.
Bash:
ln -s -T ~/.local/share/applications/online-timer.desktop ~/Desktop/online-timer
And that is literally it.

Oh, one thing I forgot to mention is to change display name of the program in the desktop too.
So, for that - open up the copied .desktop file and edit the Name and Comment fields in the file too.
Because the name in that field will still be "Firefox" and the description will be "Browse the web".

So perhaps change the name to "online-timer" and the comment to "Open online timer website in Firefox".
Otherwise, you'll just end up with two shortcuts in your menu that say Firefox! :/


For the sake of completeness - I've ran through the steps myself. So I've just installed LXDE, so I have an actual desktop with a GUI Menu system. I don't plan to use the timer application, but I come here a lot.
So I'll set up a shortcut to Linux.org instead of the timer website that @CrazedNerd originally referenced.

On my Debian installation, my firefox.desktop is actually located at /usr/share/applications/firefox-esr.desktop.
So I've copied that fie to ~/.local/share/applications and renamed it to linuxorg.desktop.
I've edited the Name= and Comment= fields to read:
Name="linux.org"
Comment=Open linux.org in FF-ESR

I've opened up the system menu in LXDE and I can immediately see my linux.org .desktop launcher in the menu. Clicking on it opens Firefox to Linux.org.
Great success!
For proof, here's a screenshot:
View attachment 15360

So that works perfectly.
The next step is to set up a symbolic-link in the desktop directory.
Bash:
ln -s -T ~/.local/share/applications/linuxorg.desktop ~/Desktop/Linux.org

LXDE doesn't seem to show the Desktop icons on the actual desktop, but opening PCManFM, I can see that the link is there.
Proof:
View attachment 15361

And clicking on it does work, but you get a prompt about it being an executable script and gives you options to execute it, execute in terminal, open it (which opens it in your text editor), or cancel.
Selecting execute opens the browser to linux.org. So the shortcut to the desktop file works.
Screenshot below:
View attachment 15362
There's no need to mess with any file-permissions.
It works pretty much exactly as described.

I'm going to log out and log back into dwm now. Using LXDE is annoying me now. The workflow just feels jarring and horrible compared to dwm! Ugh, I feel dirty now! Ha ha!
I appreciate the attempt but we have different operating systems, and i tried that (the first part, without the soft link) with both files labeled firefox.desktop i listed on my operating system and either clicking on them or left-clicking and saying "run as program" do not work...there are a pretty enormous numbers of files associated with firefox and it's hard for me to determine which of them is the executable that gets launched when i click on the icon in my favorites bar.
 
None of my posts on that particular topic mentioned using a script.
1. Copy the firefox.desktop file from wherever it currently is to ~/.local/share/applications and rename it to online-timer.desktop, or something similar.
e.g.
Bash:
cp /path/to/firefox.desktop ~/.local/share/applications/online-timer.desktop
It doesn't matter if the file is owned by root, copy it as a normal user and you should still be able to copy the file to somewhere in your home directory and the copy will be owned by you. You may or may not need to make it executable, IDK offhand.

2. Edit the Exec=/path/to/firefox field in the copied and renamed .desktop file, to add the URL to the website.
e.g.
Bash:
Exec=/path/to/firefox https://www.dateandtime.com/timer

And then, optionally - create a symbolic link on your desktop, that points to the .desktop file.
Bash:
ln -s -T ~/.local/share/applications/online-timer.desktop ~/Desktop/online-timer
And that is literally it.

Oh, one thing I forgot to mention is to change display name of the program in the desktop too.
So, for that - open up the copied .desktop file and edit the Name and Comment fields in the file too.
Because the name in that field will still be "Firefox" and the description will be "Browse the web".

So perhaps change the name to "online-timer" and the comment to "Open online timer website in Firefox".
Otherwise, you'll just end up with two shortcuts in your menu that say Firefox! :/


For the sake of completeness - I've ran through the steps myself. So I've just installed LXDE, so I have an actual desktop with a GUI Menu system. I don't plan to use the timer application, but I come here a lot.
So I'll set up a shortcut to Linux.org instead of the timer website that @CrazedNerd originally referenced.

On my Debian installation, my firefox.desktop is actually located at /usr/share/applications/firefox-esr.desktop.
So I've copied that fie to ~/.local/share/applications and renamed it to linuxorg.desktop.
I've edited the Name= and Comment= fields to read:
Name="linux.org"
Comment=Open linux.org in FF-ESR

I've opened up the system menu in LXDE and I can immediately see my linux.org .desktop launcher in the menu. Clicking on it opens Firefox to Linux.org.
Great success!
For proof, here's a screenshot:
View attachment 15360

So that works perfectly.
The next step is to set up a symbolic-link in the desktop directory.
Bash:
ln -s -T ~/.local/share/applications/linuxorg.desktop ~/Desktop/Linux.org

LXDE doesn't seem to show the Desktop icons on the actual desktop, but opening PCManFM, I can see that the link is there.
Proof:
View attachment 15361

And clicking on it does work, but you get a prompt about it being an executable script and gives you options to execute it, execute in terminal, open it (which opens it in your text editor), or cancel.
Selecting execute opens the browser to linux.org. So the shortcut to the desktop file works.
Screenshot below:
View attachment 15362
There's no need to mess with any file-permissions.
It works pretty much exactly as described.

I'm going to log out and log back into dwm now. Using LXDE is annoying me now. The workflow just feels jarring and horrible compared to dwm! Ugh, I feel dirty now! Ha ha!
HOWEVER, I just remembered my script for telling me the path of executables and i got this, so maybe my luck will change:

Code:
firefox is in $PATH and is executable

Location: /snap/bin
 
Here's a more flexible/foolproof version of a script i listed earlier, it diagnoses all of the common problems with running something from the command line, and also tells you exactly where the file is if it's in $PATH:

Code:
#!/bin/bash
#tells user if a script/binary exists, where it is located, and
#if executable privledges are turned on

SCRIPT=$0
PROGRAM_NAME=$1

#instructions
if [ $# -lt 1 ]; then
    echo "Usage:${SCRIPT##*/} [program-name]"
    exit 1
fi
#
if [ $PWD != $HOME ] && ! [ $UID = 0 ]; then
    echo "Change to $HOME, or login as root,"
    echo "Then try again."
    exit 0
fi

#creates file listing path directories
echo $PATH | awk 'BEGIN {RS=":"} {print}' | sed '/^$/d' > path-dirs

#loops through directories and tells user if file exists but is not executable
while read -r line; do
    if [ -f "$line/$1" ] && ! [ -x "$line/$1" ]; then
        echo -e "${PROGRAM_NAME##*/} is in \$PATH but is NOT executable\n"
        echo "Location: $line"
        echo "Path to file: $line/$1"
        #clean-up
        rm path-dirs
        exit 0
    fi
done < path-dirs

#tells user program is ready to use
while read -r line; do
    if [ -x "$line/$1" ]; then
        echo -e "${PROGRAM_NAME##*/} is in \$PATH and is executable\n"
        echo "Location: $line"
        echo "Path to file: $line/$1"
        #clean-up
        rm path-dirs
        exit 0
    fi
done < path-dirs

#program does is not exist in path
echo "${PROGRAM_NAME##*/} does not exist in \$PATH"

#clean-up
rm path-dirs

problem with it before was that a lot of folders in linux don't let you create files in them without root permission.
 
A random word generator that accepts arguments for more words :) You need to make a dictionary file and replace the things in the script though, first the dictionary path/filename, then the total number of words in the dictionary in the until loops:

Code:
#!/bin/bash
#random word generator
#creates an array out of a dictionary file
readarray -t word < ~/bash/RNGs/final-dict

#chooses one word by default without arguments
if [ $# -eq 0 ]; then
    randomNumber=$(date +%6N | sed 's/^0*//')
  #forces number equal to dictionary number
    until [ $randomNumber -le 611668 ]; do
        randomNumber=$(date +%6N | sed 's/^0*//')
    done

    echo "${word[$randomNumber]}"
 
    exit 0
else
    #warning for too many arguments
    if [ $# -gt 1 ]; then
        echo "Script only accepts one numeric argument"
        exit 1
    fi
    #warning for non-numeric argument
    if ! [[ $1 =~ ^[0-9] ]]; then
        echo "Usage: $0 [number-of-random-words]"
        exit 1
    fi
    #prints random words for corresponding number of arguments
    for (( i=0; i < $1; i++ )); do
        randomNumber=$(date +%6N | sed 's/^0*//')
        until [ $randomNumber -le 611668 ]; do
            randomNumber=$(date +%6N | sed 's/^0*//')
        done
        echo "${word[$randomNumber]}"
        #adds delay in execution to add unpredictability
        sleep .25
    done
fi
 
Last edited by a moderator:
In case you didn't know, you may already have a dictionary file. Check out
This was interesting and helpful to know. What surprised me was that bash can read a file of 479828 words into the array in @CrazedNerd's script in about a second. I tested on Oracle Linux in a small 1 Gbyte VPS with a single core (Oracle Cloud Free Tier, AMD).
 
Hey Jas, I'd like to see that first screenshot in #124 in your thread on Show Us A Screenshot Of Your Desktop ;)

Wiz
 
I've just created a script to convert...
  • all files with a particular extension
  • in an input directory
  • with maybe (or not) a markdown interpretation
  • to an output directory
  • to PDF format
  • using pandoc
Here's the code in full transparency (GPL-3 license), and the script would be maintained (if needed) in my GitHub account: https://github.com/gvisoc/pdf_dir
Bash:
#!/bin/sh

EXTENSION="docx"
WORK_DIR=$(pwd)
MARKDOWN=0
OUTPUT_DIR=""

function print_help {
    COMMAND="$(echo $0 | awk -F '/' '{print $NF}')"
    echo -e "$COMMAND: convert all documents in a directory to PDF."
    echo -e "\nUSAGE: $COMMAND [-e extension] [-d input dir.] [-o output dir.] [-m]"
    echo -e "\t -e extension: of the files to process, no dots (.) or wildcards,\n\t\te.g.: docx. Optional, default: docx"
    echo -e "\t -d input dir.: directory to process.\n\t\tOptional, default: current directory"
    echo -e "\t -o output dir.: directory to store the PDF files.\n\t\tOptional, default: the input directory"
    echo -e "\t -m: applies markdown parser to input files"
    echo -e "\nExamples:"
    echo -e "\t $COMMAND -e txt"
    echo -e "\t     # converts all txt files in current directory"
    echo -e "\t     # to PDF"
    echo -e "\t $COMMAND -e txt -m"
    echo -e "\t     # Same, but intepreting the content as markdown"
    echo -e "\t $COMMAND"
    echo -e "\t     # converts all docx files in current directory"
    echo -e "\t     # to PDF"
    echo -e "\t $COMMAND -d ~/Downloads"
    echo -e "\t     # converts all docx files in current user's"
    echo -e "\t     # Download directory to PDF"
    echo -e "\t $COMMAND -d ~/Downloads -o ~/Documents/out"
    echo -e "\t     # converts all docx files in current user's"
    echo -e "\t     # Download directory to PDF, placing the PDF"
    echo -e "\t     # files in Documents/out (relative to current"
    echo -e "\t     # user's home)"
}


while getopts ":d:e:o:m" OPT; do
    case "$OPT" in
        d) WORK_DIR=$(realpath "$OPTARG")
        ;;
        e) EXTENSION="$OPTARG"
        ;;
        m) MARKDOWN=1
        ;;
        o) OUTPUT_DIR=$(realpath "$OPTARG")
        ;;
        \?) print_help
        exit 1;
        ;;
    esac

    case "$OPTARG" in
        -*) if [[ "$OPT" != "m" ]]; then
            echo "ERROR: Option $OPT needs a valid argument"
            exit 2
        fi
        ;;
    esac
done

if [[ ! -n "$OUTPUT_DIR" ]]; then
    OUTPUT_DIR="$WORK_DIR"
fi

if [[ ! -n "$WORK_DIR" || ! -d "$WORK_DIR" ]]; then
    echo "Error --the directory specified, $WORK_DIR, doesn't exist."
    exit 3
fi

if [[ ! -d "$OUTPUT_DIR" ]]; then
    echo "Error --the output directory specified, $OUTPUT_DIR, doesn't exist"
    exit 3
fi

echo "Work directory: $WORK_DIR"
echo "Output directory: $OUTPUT_DIR"

FILENAMES=$(ls -1 "$WORK_DIR"/*."$EXTENSION")


# This loop is explained in this answer from StackOverflow
# https://superuser.com/a/284226
while IFS= read -r FILE || [[ -n $FILE ]]; do
    FILE="$(echo $FILE | awk -F '/' '{print $NF}')"
    FILE_OUT="$(echo "$FILE" | awk -F '.' '{print $1}').pdf"
    if [[ $MARKDOWN -eq 0 ]]; then
        pandoc -o "$OUTPUT_DIR/$FILE_OUT" "$WORK_DIR/$FILE"
    else
        pandoc -f markdown -o "$OUTPUT_DIR/$FILE_OUT" "$WORK_DIR/$FILE"
    fi
    if [[ $? -ne 0 ]]; then
        echo "Error processing file $WORK_DIR/$FILE";
        exit 4
    fi
done < <(printf '%s' "$FILENAMES")
exit 0
 
I needed an alias to show some code to copy, paste and edit without leaving the terminal.

Thanks to this thread https://unix.stackexchange.com/ques...e-contents-of-a-text-file-on-the-command-line I found "tail filename.txt" .

I made an alias with 'tail /root/.bashrc' and placed the code to be edited at the bottom of my bash.rc file.

The last 12 lines of bash.rc appear in the terminal and I am back to the prompt.

Hope this is useful to someone.

Vektor
 
I made a very simple script to test for downtime or outages with your internet service provider (ISP), but I posted it to another related thread. If you're interested, take a look here.
 
Hm. Y'know, I must have a ton of scripts. However, much as I'd like to, there would be precious little point in sharing any of 'em. Not one of them would work in a mainstream distro, as-is (which 99% of you use).......because they're all mired in concepts and "odd" locations specific to Puppy.

I wouldn't say scripting is something I particularly enjoy, but.......well, "necessity is the mother of invention", as they say. And it really IS handy to be able to automate regular, repetitive tasks.....and when I set my mind to something, I like to do it as well as I possibly can (so I don't need to keep coming back to it again & again).

(shrug...)


Mike. o_O
 
there would be precious little point in sharing any of 'em.

There's literally nothing stopping you from creating a Puppy-specific thread in the "other distributions" category.

;)

You're welcome for the idea. Now you have no excuses to not get to work sharing your scripts!

See? Ideas like that are why I make the big bucks! Oh, wait... Still, you can indeed start a Puppy-specific thread. Once grown a bit, assuming it's in the right section, you could even ask for someone to make it a sticky post.

To be clear, I'm in the process of writing another article. So, I like to encourage other folks to do the same, that is to share their knowledge.
 
@KGIII :-

Mm. It's an idea.....but I'm not so sure as I really want to start another Puppy thread on yet another forum. As a mod on both the Puppy Forum AND over at BleepingComputer, I get to decide whether I want to start threads (or not), along with where I want to put them AND what I want to put in them. I post a ton of stuff and am kept quite busy on the Puppy Forum, and I started 'Puppy Corner' at BC several years ago, long before I joined the staff.....which, even now, I keep adding to as & when. It helped that both of the Linux section mods were also avid Puppy users themselves, so they were quite happy when I suggested the thread.....

I'll have to think about that one! :D


Mike. :p
 
It helped that both of the Linux mods were also avid Puppy users themselves, so they were quite happy when I suggested the thread.....

I'd like to think I portrayed happiness! ;)

But, I can DEFINITELY relate to some of the rest. Man, I give a whole lot of hours to the Linux community. I'm spread pretty thin as it is, so I mostly just keep up with what I consider my main priorities. I have an active life outside of my Linux geekiness. With the COVID-restrictions now over, it means an even greater effort must be made to ensure I keep what I consider a healthy balance.

Still, I'd say that Linux.org is worthy of your contributions - should you ever change your mind (and have time).
 

Members online


Top