You are not logged in.
Say you have a directory tree of your favorite songs and albums, this little function will make a recursive list of all files, match them against the argument you've passed and play the matched one. If multiple matches are found, it will play a random one.
# Mplayer Find Play mpfp () { MUSICDIR="${HOME}"/music/ ISGLOBSTAR='no' shopt -p | grep '-s globstar' > /dev/null if [[ $? -eq 0 ]] ; then ISGLOBSTAR='yes' ; fi shopt -s globstar pushd "${MUSICDIR}" > /dev/null mplayer "$((((stat ** -c '%n' | egrep '*.*' ) | grep "$1") | sort -R) | tail -n1)" popd > /dev/null if [[ "${ISGLOBSTAR}" == 'no' ]] ; then shopt -u globstar ; fi }
What the heck is the point of the stat call? globstar is notoriously slow compared to find on large hierarchies as it has to expand in place rather than iterate...
mpfp() {
local musicdir=/path/to/music
find "$musicdir" -type f -name "*$1*" -print0 | shuf -zn1 | xargs -0 mplayer
}
Last edited by falconindy (2011-08-03 01:43:13)
Offline
@hauzer:
If you run that in a subshell you won't need to restore shopt or pushd.
E.g.
mpfp() {
(
shopt -s globstar
cd $MUSICDIR
mplayer ...
)
}
I use something very similar actually:
ms ()
{
xargs -0 -a <(locate -0 /2/music/"*$1*" | grep -aizZ "$2" | grep -aizZ "$3") mplayer
}
The problem I have is that I want to do an "ANDed" grep search.
The above code allows for an extra two arguments which must match the filename.
They can be blank though.
So
ms foo bar
would match
barfoo.mp3
Offline
@falconindy:
If you pipe to xargs like that, it won't give mplayer a stdin so you won't be able to control it.
You need to use xargs -a and let its stdin be a tty (which it will then give to mplayer)
Offline
I thought of using find but I guess it's just a matter of choice. Of course, it's always better to use utilities that are meant for a specified job, but excercising my poor bash skills one way or another can't hurt. I'll thinker around this for a while. Oh, and thanks for the subshell tip, Procyon.
Vanity of vanities, saith the Preacher, vanity of vanities; all is vanity.
What profit hath a man of all his labour which he taketh under the sun?
All the rivers run into the sea; yet the sea is not full; unto the place from whence the rivers come, thither they return again.
For in much wisdom is much grief: and he that increaseth knowledge increaseth sorrow.
Offline
@falconindy:
If you pipe to xargs like that, it won't give mplayer a stdin so you won't be able to control it.
You need to use xargs -a and let its stdin be a tty (which it will then give to mplayer)
Sure, alternatively you could just read the result of the find|shuf and pass it to mplayer.
Offline
# mkdir /etc/cron.hourly
# ln -s ~/pmsync.sh /etc/cron.hourly/
~/pmsync.sh:
#!/bin/bash
pacman -Sy
Offline
# mkdir /etc/cron.hourly
# ln -s ~/pmsync.sh /etc/cron.hourly/~/pmsync.sh:
#!/bin/bash pacman -Sy
And?
Do you run it to know how many packages you can update?
http://bashlnx.blogspot.com/2011/05/hey … rt-ii.html
Offline
Do you run it to know how many packages you can update?
http://bashlnx.blogspot.com/2011/05/hey … rt-ii.html
Yep.
Thanks. Now my ~/pmsync.sh looks like:
#!/bin/bash
mkdir --parents /dev/shm/$USER/pacman/sync
ln --force --symbolic /var/lib/pacman/local /dev/shm/$USER/pacman
fakeroot /usr/bin/pacman --dbpath /dev/shm/$USER/pacman --sync --refresh
Last edited by Pooh-Bah (2011-08-05 06:16:32)
Offline
Small update.
~/pmsync.sh
#!/bin/bash
mkdir --parents /dev/shm/$USER/pacman/sync
ln --force --symbolic /var/lib/pacman/local /dev/shm/$USER/pacman
fakeroot /usr/bin/pacman --sync --dbpath /dev/shm/$USER/pacman --refresh
PKG=$(/usr/bin/pacman --query --dbpath /dev/shm/$USER/pacman --quiet --upgrades | wc -l)
if [[ $PKG = 0 ]]; then
echo "is up to date" > /dev/shm/$USER/pacman/PKG
elif [[ $PKG = 1 ]]; then
echo "1 new package" > /dev/shm/$USER/pacman/PKG
else
echo "$PKG new packages" > /dev/shm/$USER/pacman/PKG
fi
~/.tmux.conf:
...
set -g status-left '... #[fg=black](#[default]#[fg=magenta,nobright]#(cat /dev/shm/$USER/pacman/PKG)#[default]#[fg=black])#[default]'
screenshot:
(all colors & configs by Jason W. Ryan (thank you), with small fixes.)
Offline
One of the first bash scripts I created was to pull all my git projects stored in one directory. Very simple.
for x in /home/atm/git/*;
do
echo "Entering $x"
cd $x;
git pull;
cd ..;
done
Offline
I wrote a script that will show me the domain name servers of ip addresses that are currently connected to me. First it shows the short option from dig then the long one.
#! /bin/bash
c=$( netstat --tcp --numeric | awk 'NR>2 {print $5}'| sort -n -t : -k 2,2 | uniq | wc -l)
d=$( echo $c )
if [ "$d" -lt "23" ] && [ "$d" -gt "0" ]; then
echo "Domains / Nameservers"
x=$( netstat --tcp --numeric | awk 'NR>2 {print $5}'| sort -n -t : -k 2,2 | uniq )
y=$( netstat --tcp --numeric | awk 'NR>2 {print $5}'| sort -n -t : -k 2,2 | uniq | sed -e 's/\:.*//' )
a=$( for i in $y; do
dig @8.8.8.8 -x $i +short | sed 's/[.]$//g'
done )
b=$( for i in $x; do
dig @8.8.8.8 -x $i | grep -e "SOA" -e "PTR" | awk '{print $5}' | grep "." | sed 's/[.]$//g'
done )
echo -e "$a \n$b" | grep "." | cut -c 1-21 | sort | uniq
echo " "
fi
exit
8.8.8.8 (Google) is what is used to look up dns records (my router was too slow). Also, the if then statement at the beginning
if [ "$d" -lt "23" ] && [ "$d" -gt "0" ]; then
is to disable the script if 23 or more ip addresses are connected. Change it to whatever suits you best. I put that there for when I am downloading torrents.
Offline
Script I made to change hostname then change back on the fly. The "xhost +" is insecure but if you reboot / restart x (to keep new hostname) or change hostname back by re-running the script it will change back to "xhost -". I had to use "xhost +" because nothing else was working without a restart. Because of this it should be more cross compatible between DE's / WM's. The variables at the top of the script (oldhost and newhost) must be set manually before you run the script. What this script does is changes your old host name in your rc.conf and hosts file then runs the hostname command. After that it restarts the network and network manager (if you do not use networkmanager (you use wicd or whatever) then substitute that for something else). Then it flushes your dns and ram caches.
#! /bin/bash
oldhost=yourcurrenthostname
newhost=newhostname1
host=$(hostname)
if [[ $EUID -ne 0 ]]; then
echo "This script needs to be run as root." 1>&2
exit 1
fi
if [ "$host" = "$oldhost" ]; then
echo "Spoofing hostname to $newhost. To switch back to $oldhost rerun this script."
sed -i 's/'$oldhost'/'$newhost'/g' /etc/rc.conf
sed -i 's/'$oldhost'/'$newhost'/g' /etc/hosts
hostname $newhost
/etc/rc.d/network restart
/etc/rc.d/networkmanager restart
/etc/rc.d/nscd restart
sync; echo 3 > /proc/sys/vm/drop_caches
xhost +
else
echo "Switching hostname back to $oldhost."
hostname $oldhost
sed -i 's/'$newhost'/'$oldhost'/g' /etc/rc.conf
sed -i 's/'$newhost'/'$oldhost'/g' /etc/hosts
/etc/rc.d/network restart
/etc/rc.d/networkmanager restart
/etc/rc.d/nscd restart
sync; echo 3 > /proc/sys/vm/drop_caches
xhost -
fi
exit
Offline
Wrote a pair of bash functions to make (repo and build dir) navigation a little easier. 'up' will try to traverse up the current hierarchy until it finds a matching file. Down will traverse down from $PWD until it finds a matching directory or file. Both are atomic -- that is, they will not unnecessarily disturb $OLDPWD so that 'cd -' will still function as if you changed directories only once.
down:
down() {
local OPTIND=0 flag= match= pred=
local -i i=0 first=0
local -a matches
_goto() {
if [[ -d $1 ]]; then
cd "$1"
else
cd "${1%/*}"
fi
}
while getopts 'bcdflps1' flag; do
case $flag in
b|c|d|f|l|p|s) pred="-type ${1#-}" ;;
1) first=1 ;;
*) return 1 ;;
esac
done
shift $(( OPTIND - 1 ))
# sort by depth
while IFS=$'\t' read -r _ match; do
matches[++i]=$match
done< <(find . $pred -name "$1" | awk -F'/' '{ printf "%s\t%s\n",NF,$0 }' | sort -n)
if (( ! ${#matches[*]} )); then
echo "no matches"
return 1
fi
if (( i == 1 || first )); then
_goto "${matches[1]}"
else
if (( $# == 1 )); then
i=0
for match in "${matches[@]}"; do
(( ++i ))
printf '%d) %s%s\n' "$i" "${matches[i]}" "$([[ -d ${matches[i]} ]] && printf '/')"
done
else
if (( $2 > i )); then
return 1
fi
_goto "${matches[$2]}"
fi
fi
}
up:
up() {
local x= traverse= curpath=
[[ $1 ]] || { cd ..; return; } # default to 1 level
for x; do
if [[ $x == +([[:digit:]]) ]]; then
(( x == 0 )) && return # noop
# build a path to avoid munging OLDPWD
while (( x-- )); do
traverse+=../
done
cd "$traverse"
else
curpath=$PWD
while [[ $curpath && ! -e $curpath/$x ]]; do
curpath=${curpath%/*}
done
if [[ $curpath ]]; then
cd "$curpath"
else
printf "error: failed to locate \`%s' in a parent directory\n" "$x"
return 1
fi
fi
done
}
Last edited by falconindy (2011-08-13 14:25:20)
Offline
Amidoinitrite? Script similar to ratpoison/StumpWM's banish command; uses xrandr, grep, and sed to get resolution; powered by xdotool:
#!/bin/bash
WIDTH=`xrandr 2> /dev/null | grep "current [0-9]* x [0-9]*" | sed -e 's/^[^.]*current //' | sed -e 's/ x [^.]*//'`
HEIGHT=`xrandr 2> /dev/null | grep "current [0-9]* x [0-9]*" | sed -e 's/^[^.]*current [^.]* x //'`
xdotool mousemove $WIDTH $HEIGHT
Last edited by woddfellow2 (2011-08-11 08:50:08)
1-Crawl 2-Cnfg 3-ATF 4-Exit ?
Offline
@woddfellow2: You can condense grep and sed with sed -n 's///p'. As well as group multiple sed commands with ;
The cursor is bound, though:
xdotool mousemove 9999 9999
Offline
Bug fix:
#!/bin/bash
WIDTH=`xrandr 2> /dev/null | grep "current [0-9]* x [0-9]*" | sed -e 's/^[^.]*current //' | sed -e 's/ x [^.]*//'`
HEIGHT=`xrandr 2> /dev/null | grep "current [0-9]* x [0-9]*" | sed -e 's/, maximum [^.]*//' | sed -e 's/^[^.]*current [^.]* x //'`
xdotool mousemove $WIDTH $HEIGHT
(The old version got the height of the maximum instead of the current)
@woddfellow2: You can condense grep and sed with sed -n 's///p'. As well as group multiple sed commands with ;
Maybe I should look into that...
The cursor is bound, though:
xdotool mousemove 9999 9999
xdotool mousemove 9999 9999 seemed like a kluge, and not futureproof enough, in case we eventually end up with >= 10,000 pixels.
1-Crawl 2-Cnfg 3-ATF 4-Exit ?
Offline
The script I use if devede / mencoder gives me problems (run it from the same directory as your video file):
#! /bin/bash
export VIDEO_FORMAT=NTSC
echo "What is the name of the movie including file extension?"
read moviename
ffmpeg -i $moviename -y -target ntsc-dvd -sameq -aspect 16:9 out.mpg &&
dvdauthor --title -o dvd -f out.mpg &&
dvdauthor -o dvd -T &&
mkisofs -dvd-video -o dvd.iso dvd/ &&
exit
Probably don't need all those ampersands but it has worked well for me.
Last edited by dodo3773 (2011-08-13 00:52:37)
Offline
This script adds pdf "title" metadata from the filename using exiftool to any pdfs in the current directory. Maybe someone can suggest how to clean it up a bit...
ls -1 *.pdf | sed 's/\(.*\)\..*/\1/' > names.txt
ls -1 *.pdf > names2.txt
cat names.txt | sed 's/^/"/' | sed 's/$/"/' > names3
cat names2.txt | sed 's/^/"/' | sed 's/$/"/' > names4
awk 'NR==FNR{a[FNR]=$0;next} {print a[FNR],$0}' names3 names4 > newnames
sed 's/^/exiftool -Title=/' newnames > script
chmod +x script
./script
rm names.txt
rm names2.txt
rm names3
rm names4
rm newnames
rm script
exiftool -delete_original *.pdf
Last edited by darkbeanies (2011-08-14 23:27:24)
Offline
The script is rather self-explanatory, I wrote it for my brother.
#!/bin/bash
#
# Create a ready to use XPAM Battle.Net account using mailinator as the email provider.
# Usage: xpamreg username password
#
###############
## VARIABLES ##
###############
#
curlargs="-q -s -A 'Mozilla/5.0 (X11; Linux i686; rv:5.0) Gecko/20100101 Firefox/5.0'"
#
###############
## FUNCTIONS ##
###############
#
# Mailinator creates a random email on it's homepage, this function just extracts it
# via grep and sed magic
#
get_tmpmail () {
curl ${curlargs} http://www.mailinator.com/ | grep 'maildir.jsp?email' | tail -n1 | \
sed 's/.*email=.*>\(.*\)<\/a>.*/\1/'
}
#
# A unique authentication cookie is created every time the registration page is visited.
# First we need to lure the website into giving us one by making a dummy connection.
# We need the token for POSTing it to the registration form and the cookie to verify with
# the website that we're not a script. ;)
#
register_acc () {
echo -n " Creating account $1..."
local cookiejar="/tmp/xpamreg-cookiejar-${RANDOM}"
local authtoken=$(curl ${curlargs} -c "${cookiejar}" http://app.eurobattle.net/register | \
grep -A1 'all fields are required' | tail -n1 | \
sed 's/.*value="\(.*\)".*/\1/')
curl ${curlargs} -b "${cookiejar}" \
--data-urlencode "authenticity_token=${authtoken}" \
--data-urlencode "user[name]=$1" \
--data-urlencode "user[password]=$2" \
--data-urlencode "user[password_confirmation]=$2" \
--data-urlencode "user[email]=$3" \
--data-urlencode "commit=Create Account" app.eurobattle.net > /dev/null
echo ' Account created!'
}
#
# We first extract the url to the email just recieved and then extract the verification
# url.
#
verify_acc () {
local emailurl=
# Check if the verification email has arrived
echo ' Starting verification...'
echo " Waiting for email at $1..."
while true ; do
emailurl=$(curl ${curlargs} "http://www.mailinator.com/maildir.jsp?email=$1")
emailurl=$(echo ${emailurl} | grep 'register@eurobattle.net')
# If grep didn't fail then we're sure the email is there and we can extract the
# verification url.
if [[ $? -eq 0 ]] ; then
echo ' Email has arrived!'
emailurl=$(echo ${emailurl} | sed 's/.*<a href=\/\(.*\)>C.*/\1/')
break
fi
echo ' No email has arrived, yet...'
sleep 1
done
echo ' Verifying...'
local verifyurl=$(curl ${curlargs} "http://www.mailinator.com/${emailurl}" | \
grep 'http://app1.eurobattle.net' | sed 's/.*<a href="\(.*\)".*/\1/')
curl ${curlargs} "${verifyurl}" > /dev/null
echo ' The account has been verified!'
}
#
##########
## MAIN ##
##########
#
echo Registering account...
email=$(get_tmpmail)
register_acc $1 $2 "${email}"
verify_acc "${email}"
echo Registration completed!
exit 0
I still need to add error checking, though.
Last edited by hauzer (2011-08-14 03:32:27)
Vanity of vanities, saith the Preacher, vanity of vanities; all is vanity.
What profit hath a man of all his labour which he taketh under the sun?
All the rivers run into the sea; yet the sea is not full; unto the place from whence the rivers come, thither they return again.
For in much wisdom is much grief: and he that increaseth knowledge increaseth sorrow.
Offline
Whew, I've managed to port this thing to Windows! I guess you can port any bash script like this. I used a basic MSYS installation, added a compiled curl binary and striped all the unnecessary stuff. Execution is at least two times slower than in the native environment, but that's subjective and understandable. Here's the "package" download link if anyone's interested: http://ompldr.org/vOXdjcA
Vanity of vanities, saith the Preacher, vanity of vanities; all is vanity.
What profit hath a man of all his labour which he taketh under the sun?
All the rivers run into the sea; yet the sea is not full; unto the place from whence the rivers come, thither they return again.
For in much wisdom is much grief: and he that increaseth knowledge increaseth sorrow.
Offline
Already numerous backup scripts, but it is the only bash script I use that I wrote myself. Makes an incremental backup using hardlinks:
#!/bin/bash
# initial parameters
DRY_RUN=0
VEBROSE=0
RSYNC_ARGS=""
# function which prints usage information
usage () {
echo "Usage: ${0##*/} [options] SRC BAK"
echo
echo " SRC source directory "
echo " BAK backup directory "
echo
echo "Options:"
echo " -h print this info"
echo " -x <pattern> specify excludes (see rsync man page)"
echo " -f <file> use an external exclude file for rsync"
echo " -z compress files during transfer"
echo " -v verbose output"
echo " -n perform a dry-run, no backup is made"
echo
}
# parse options
while getopts "hx:e:zvn" opt
do
case $opt in
h) usage
exit 0 ;;
x) RSYNC_ARGS+=" --exclude='$OPTARG'" ;;
e) RSYNC_ARGS+=" --exclude-from=$OPTARG" ;;
z) RSYNC_ARGS+=" -z" ;;
v) VERBOSE=1
RSYNC_ARGS+=" -v" ;;
n) DRY_RUN=1
RSYNC_ARGS+=" -n" ;;
*) usage
exit 1;;
esac
done
# set source and destination directories
shift $(($OPTIND-1))
if [[ -z "$1" || -z "$2" ]]; then
echo "ERROR: missing argument(s)"
usage
exit 1
else
srcdir="$1"
bakdir="$2"
fi
# paranoia sanity check, shouldn't happen
if [[ -z "$bakdir" ]]; then
echo "ERROR: backup directory empty"
exit 1
fi
# create the backup ID
id="$(hostname)-$(date +%Y-%m-%d-%H.%M.%S-%N)"
if ((DRY_RUN)); then
echo "==> dry-run, no actual backup is made!"
else
echo "==> making backup of $srcdir to $bakdir/$id"
mkdir -p "$bakdir/$id"
fi
# rsync the contents of the source to the destination directory:
# -> creates hardlinks of unaltered files against the most recent backup that was made
# -> uses relative paths to preserve full path on the backup, so that
# a backup of /home/user/foo on /backup becomes /backup/id/home/user/foo
rsync -aR $RSYNC_ARGS --link-dest="$bakdir/recent" "$srcdir/" "$bakdir/$id"
rc=$?
if (($rc)); then
echo "ERROR: rsync exited with value $rc"
exit 1
fi
# update link pointing to most recent backup
ln -sfT "$bakdir/$id" "$bakdir/recent"
exit 0
Offline
this is my flac batch-tagging script based on EAC cue file, relies heavily on sed. dirty hack, poorly written since I can't get splitting-converting-tagging to work in one shot using shnsplit
first we split the audio file with shnsplit into separate wav files, then we convert the wav files to flac. the result are files with name split-track*.flac
I assume that the available comments are only ALBUM, ARTIST, and DISCID. some cue files have more than that.
applymflac.sh <utf8-or-ascii-but-not-that-annoying-SJIS-please>.cue
#!/bin/sh
TOTALTRACKS=`tail -n 3 $1 | sed -e 's/ TRACK //' -e 's/ AUDIO//' -e 'q'`
ALBUM=`sed -e '1,/PERFORMER/ d' -e 's/TITLE //' -e 's/"//g' -e 'q' $1`
ARTIST=`sed -e '1,/REM/ d' -e 's/PERFORMER //' -e 's/"//g' -e 'q' $1`
DISCID=`sed -e '/REM DISCID/ s/REM DISCID //' -e 'q' $1`
lump=`sed -e '1,/FILE/ d' -e 's/ TRACK.*//g' -e 's/ INDEX.*//g' $1`
for i in `seq 1 $TOTALTRACKS`;
do
test $i -lt 10 && TRACKNUMBER=`echo 0$i` || TRACKNUMBER=$i
target=`echo split-track$TRACKNUMBER.flac`
echo "Applying tags for track $TRACKNUMBER, filename: $target"
TITLE=`echo $lump | sed -e 's/TITLE //' -e 's/"//' -e 's/"//' | sed 's/ TITLE.*//' `
lump=`echo $lump | sed -e 's/TITLE //' -e 's/"//' -e 's/"//' | sed "s/$TITLE //" `
echo $TRACKNUMBER $TITLE
metaflac --set-tag="TITLE=$TITLE" --set-tag="ALBUM=$ALBUM" --set-tag="ARTIST=$ARTIST" --set-tag="TRACKNUMBER=$TRACKNUMBER" --set-tag="TOTALTRACKS=$TOTALTRACKS" --set-tag="DISCID=$DISCID" $target
done;
if only I knew a proper way to use shnsplit, I won't spend the whole afternoon to learn sed and write this
oh yeah, metadata tags are more important than filenames to me...
Last edited by ShionjiYuuko (2011-08-21 10:02:00)
始まりの荒野を独り もう歩き出してるらしい、僕は灰になるまで僕で有り続けたい
http://about.me/nnhnkn | http://identi.ca/nnhzkn
Offline
I had to put a limited access guest computer together so I put this right before the daemons section in rc.multi:
timeofday=$( date | awk '{print $4}' | cut -f"1" -d":" )
if [ "$timeofday" -gt "6" ] && [ "$timeofday" -lt "22" ] ; then
echo "boot"
else
poweroff
fi
If it is before 6 A.M. or after 10 P.M. the computer will not boot. Right before it loads the daemons it will just shut down.
Last edited by dodo3773 (2011-08-21 18:11:29)
Offline
hr=$(date +%H') (( hr < 6 || hr > 22 )) && poweroff
Nice. Talk about clean. I should use "or" more often. I probably won't go re-write it but I will certainly be using it in the future. Thanks for the tip.
Offline