You are not logged in.

#3001 2017-05-12 04:58:17

LeoMingo
Member
Registered: 2017-05-07
Posts: 20

Re: Post your handy self made command line utilities

I have a directory in another system's partition, in order to get to that directory more quickly, here is what I do:

if mount | grep $ANOTHER_SYS > /dev/null; then
  cd $DIR
else
  mkdir -p $ANOTHER_SYS
  mount /dev/sdaN $ANOTHER_SYS
  cd $DIR
fi

And all you need to do is give the script a name, then evaluate the script using source command("source " or simply ". ").

Last edited by LeoMingo (2017-05-12 05:05:33)

Offline

#3002 2017-05-12 05:04:49

LeoMingo
Member
Registered: 2017-05-07
Posts: 20

Re: Post your handy self made command line utilities

jasonwryan wrote:

Why would you think running, of all things, a web browser as root would be a good idea?

For some reasons I guess, it's risky but someone should have full access to his system, and maybe lazy enough he just does not want to type all the requirements to gain root access as a non root user? (Like me, except for games and irc, I would love to try everything as a root, bad habit I guess tongue)

Offline

#3003 2017-05-12 05:10:29

jasonwryan
Anarchist
From: .nz
Registered: 2009-05-09
Posts: 30,424
Website

Re: Post your handy self made command line utilities

It's worse than laziness; given your lack of any remotely plausible rationale, it is foolishness.


Arch + dwm   •   Mercurial repos  •   Surfraw

Registered Linux User #482438

Offline

#3004 2017-05-12 06:13:58

LeoMingo
Member
Registered: 2017-05-07
Posts: 20

Re: Post your handy self made command line utilities

jasonwryan wrote:

It's worse than laziness; given your lack of any remotely plausible rationale, it is foolishness.

Probably

Offline

#3005 2017-05-12 07:59:11

broken pipe
Member
Registered: 2010-12-10
Posts: 243

Re: Post your handy self made command line utilities

Lineage OS and OpenGapps Downloader

It downloads today's rom for my two devices + appropriate gapps + su for root access.
I run this script once a day as cronjob on my rpi. if you want to get an automated email see below.

#!/bin/bash

DATE_FORMAT="$(date +%Y%m%d)"
DATE_FORMAT_SAVE="$(date -I)"

# Start editing here
DIR_ROM="/path/to/your/roms"
FIRST_ROM="osprey"
SECOND_ROM="falcon"
GAPPS_VARIANT="pico" 	# aroma, super, stock, full mini, micro, nano, pico, tvstock
GAPPS_ANDROID="7.1"	# 7.1, 5.0, 5.1, 6.0, 7.0, 7.1
GAPPS_PLATFORM="arm"	# arm, arm64, x86, x86_64
EMAIL_ADDRESS="email@address.com"
EMAIL_SUBJECT="New Roms available"
# End editing here

URL_FIRST_ROM="https://lineageos.mirrorhub.io/full/$FIRST_ROM/$DATE_FORMAT/lineage-14.1-$DATE_FORMAT-nightly-$FIRST_ROM-signed.zip"
URL_SECOND_ROM="https://lineageos.mirrorhub.io/full/$SECOND_ROM/$DATE_FORMAT/lineage-14.1-$DATE_FORMAT-nightly-$SECOND_ROM-signed.zip"
URL_SU="https://mirrorbits.lineageos.org/su/addonsu-arm-signed.zip"
URL_GAPPS="https://github.com/opengapps/arm/releases/download/$DATE_FORMAT/open_gapps-$GAPPS_PLATFORM-$GAPPS_ANDROID-$GAPPS_VARIANT-$DATE_FORMAT.zip"

validate_url () {
  if [[ `wget -S --spider $1  2>&1 | grep 'HTTP/1.1 200 OK'` ]]; then echo "true"; fi
}


if [[ $(validate_url "$URL_FIRST_ROM") ]] || [[ $(validate_url "$URL_SECOND_ROM") ]]; then

	cd "$DIR_ROM" || exit

	find "$DIR_ROM" -type f -iname '*.zip' -mtime +3 -delete
	find "$DIR_ROM" -type f -iname '*opengapps*' -mtime +1 -delete

	if [ $(validate_url "$URL_FIRST_ROM") ]; then
		wget -qc "$URL_FIRST_ROM" -O "$DATE_FORMAT_SAVE-$FIRST_ROM.zip"
	fi

	if [ $(validate_url "$URL_SECOND_ROM") ]; then
		wget -qc "$URL_SECOND_ROM" -O "$DATE_FORMAT_SAVE-$SECOND_ROM.zip"
	fi

	if [ $(validate_url "$URL_SU") ]; then
		wget -qc "$URL_SU" -O "$DATE_FORMAT_SAVE-su.zip"
	fi

	wget -qc "$URL_GAPPS" -O "$DATE_FORMAT_SAVE-opengapps_$GAPPS_ANDROID_$GAPPS_VARIANT.zip"

	printf "$(ls -R $DIR_ROM)" | mail -s "$EMAIL_SUBJECT" -r "$HOSTNAME<noreply@>" "$EMAIL_ADDRESS"
fi

For sending mail you'll need ssmtp and s-nail

/etc/ssmtp/ssmtp.conf (Gmail example)

root=postmaster
mailhub=mail
hostname=rpi
AuthUser=address@gmail.com
AuthPass=Pas$w0rd
FromLineOverride=YES
mailhub=smtp.gmail.com:587
UseSTARTTLS=YES

Have fun smile

Last edited by broken pipe (2017-05-12 08:01:14)

Offline

#3006 2017-05-12 09:43:16

Alad
Wiki Admin/IRC Op
From: Bagelstan
Registered: 2014-05-04
Posts: 2,418
Website

Re: Post your handy self made command line utilities

The validate_url makes no sense to me; a 200 OK on the first attempt does not guarantee a success on the second, of which you do no error checking (the ubiquitous race condition). Better would be something like:

curl_fancy_error() {
  if ! curl --fail -LsS "$@"; then
    printf '%s\n' >&2 "Some fancy error"
  fi
}

for f in "$url_first_rom" "$url_second_rom"; do
  curl_fancy_error "$f" -o "$date_format_save-$f"
done

Note that I also used lower-case for variables, as upper-case variables may be reserved for something else (e.g, bash-internal variables)

find "$DIR_ROM" -type f -iname '*.zip' -mtime +3 -delete

Why you date the zip archives yet delete them on every run?

printf "$(ls -R $DIR_ROM)"

http://mywiki.wooledge.org/ParsingLs

Last edited by Alad (2017-05-12 09:44:41)


Mods are just community members who have the occasionally necessary option to move threads around and edit posts. -- Trilby

Offline

#3007 2017-05-12 15:40:03

Aerial Boundaries
Member
Registered: 2015-05-15
Posts: 26

Re: Post your handy self made command line utilities

Learning C right now, I'm using this to test oneliners.

#!/bin/bash

echo "#include <stdio.h>
int main(void)
{ $1
return 0; }" | \
    gcc -o testfile -xc - || exit 1

./testfile
rm testfile

E.g.: c_oneliner_test 'printf("foo");'

Offline

#3008 2017-05-12 17:13:49

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,330
Website

Re: Post your handy self made command line utilities

That's creative Aerial, but not really useful in the long run.  You may want to get your $EDITOR set up with some templates or related auto-boilerplate and some bindings for compiling/running.  If you use a good editor like vim, or even a bad editor like emacs, all this is well documented with ample examples around.  If your editor is neither good nor bad, but is ugly, then there's no help.


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#3009 2017-05-12 17:20:08

ewaller
Administrator
From: Pasadena, CA
Registered: 2009-07-13
Posts: 20,209

Re: Post your handy self made command line utilities

Trilby wrote:

...or even a bad editor like emacs, ...

Hey!

Last edited by ewaller (2017-05-12 17:33:49)


Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
Sometimes it is the people no one can imagine anything of who do the things no one can imagine. -- Alan Turing
---
How to Ask Questions the Smart Way

Offline

#3010 2017-05-12 21:24:42

Alad
Wiki Admin/IRC Op
From: Bagelstan
Registered: 2014-05-04
Posts: 2,418
Website

Re: Post your handy self made command line utilities

Real hackers use notepad.exe in wine...


Mods are just community members who have the occasionally necessary option to move threads around and edit posts. -- Trilby

Offline

#3011 2017-05-12 21:51:55

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,330
Website

Re: Post your handy self made command line utilities

While it in no way suits me, notepad++ is actually quite a capable editor.


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#3012 2017-05-13 00:09:06

Alad
Wiki Admin/IRC Op
From: Bagelstan
Registered: 2014-05-04
Posts: 2,418
Website

Re: Post your handy self made command line utilities

Probably more for the grr thread, but when I was using notepad++, I had to use random third-party DLLs to get the same basic stuff I had in vim/emacs. E.g., reindent a block of code? Get a DLL from sourceforge...

edit: I just noticed my curl post above does not exit the script when curl fails. On a similar note, curl supports writing the HTTP code directly to stdout, so you could make a caste statement depending on 200, 404, etc.

Last edited by Alad (2017-05-13 00:12:00)


Mods are just community members who have the occasionally necessary option to move threads around and edit posts. -- Trilby

Offline

#3013 2017-05-13 13:30:55

Aerial Boundaries
Member
Registered: 2015-05-15
Posts: 26

Re: Post your handy self made command line utilities

Trilby wrote:

That's creative Aerial, but not really useful in the long run.  You may want to get your $EDITOR set up with some templates or related auto-boilerplate and some bindings for compiling/running.  If you use a good editor like vim, or even a bad editor like emacs, all this is well documented with ample examples around.  If your editor is neither good nor bad, but is ugly, then there's no help.

You're right. I've installed a template package on the "bad editor" (though with the good editor's bindings!). Now for the second aspect.

Offline

#3014 2017-05-24 11:49:55

kokoko3k
Member
Registered: 2008-11-14
Posts: 2,421

Re: Post your handy self made command line utilities

I'm fighting with a cifs mount since long time.
When the server disconnects, all the associated handles and processes goes in a stall state, and working is impossible (plasmashell itself freezes).
I finally sorted it out by first mounting the cifs share, and then mounting the mounted cifs share with bindfs.
The key is that bindfs is a fuse filesystem, so it runs in userspace, and the user can just kill his process to invalidate all the stale handles and free the associated processes.
Long story short, the following will take care of mounting the share, polling if it is alive, and if not unmounting it and iterate.

Of course, edit $cifs_opts as you need it and start it as root user.
It works!

#!/bin/bash

# smbbind.sh share                   mountpoint
# smbbind.sh "//SERVER/SHARE" "/mnt/somewhere"

check_every=30   #Seconds
timeout_after=5  #Seconds
restart_after=30 #Seconds

hide_path=~/.smbbind/
cifs_opts="rw,cache=strict,username=nt_user,password=nt_pass,domain=nt_domain,uid=0,noforceuid,gid=0,noforcegid,file_mode=0755,dir_mode=0755,nounix,serverino,rsize=61440,wsize=57344,actimeo=60,_netdev"

share="$1"
bind_mountpoint="$2"

function clean {
	#Umount bindfs, next umount cifs, then exit.
	echo [..] Cleaning...
	#The only open handle opened on the cifs share should be the bindfs one.
	echo [..] forcing umounting bindfs on "$bind_mountpoint"
	kill -9 $bindfs_pid
	umount -f "$bind_mountpoint"
	echo [OK] Done.
	# Umounted bindfs, cifs should umount without problems
	echo [..] Forcing umounting cifs on "$cifs_mountpoint"
	umount -f "$cifs_mountpoint"
	umount -l "$cifs_mountpoint"
	echo [OK] Done cleaning.
}

function finish {
        echo exiting...
	clean
	trap exit INT TERM EXIT
	exit
}

trap finish INT TERM EXIT

#Prepare environment
    mkdir $hide_path &>/dev/null
    cifs_mountpoint=$hide_path/$(echo $bind_mountpoint|tr '/' '_')
    mkdir -p $cifs_mountpoint &>/dev/null
    mkdir -p $bind_mountpoint &>/dev/null

while true ; do
       
    #Mount things:
        echo [..] mounting cifs "$share" on "$cifs_mountpoint"
        if timeout 10 mount.cifs "$share" "$cifs_mountpoint"  -o $cifs_opts ; then
            echo [OK] mounted cifs "$share" on "$cifs_mountpoint"

            echo [..] mounting bind "$cifs_mountpoint" on "$bind_mountpoint"
            bindfs "$cifs_mountpoint" "$bind_mountpoint"
            #Getting the pid of bindfs is tricky.
            bindfs_pid=$(ps -eo pid,args|grep bindfs |grep "$cifs_mountpoint" |grep "$bind_mountpoint" |cut -d " " -f 1)
            echo [OK] mounted bind "$cifs_mountpoint" on "$bind_mountpoint"
            
            #Check them
                echo [OK] Start Main check cycle, whill check every $check_every seconds...
                while true ; do
                    if ! timeout -k 1 $timeout_after ls "$bind_mountpoint" &>/dev/null ; then
                        echo no answer from bindfs for "$bind_mountpoint"
                        clean
                        break
                            #else
                        #echo Share is alive
                    fi
                    sleep $check_every
                done

                else
            echo [!!] Cannot mount "$share" on "$cifs_mountpoint"
        fi
                
    echo [..] Waiting $restart_after seconds: $(date) 
    sleep $restart_after

done

-EDIT-
Made a systemd service for it too, nothing special:

koko@Gozer# cat /etc/systemd/system/mount_nas.service
[Unit]
Description=Mont NAS with cifs and bindfs

[Service] 
Type=simple
ExecStart=/path/to/smbbind.sh //SERVER/SHARE$ /mnt/nas

[Install]
WantedBy=default.target

Last edited by kokoko3k (2017-05-24 11:54:28)


Help me to improve ssh-rdp !
Retroarch User? Try my koko-aio shader !

Offline

#3015 2017-05-24 14:55:57

adam_danischewski
Banned
Registered: 2016-05-06
Posts: 23
Website

Re: Post your handy self made command line utilities

Here is a simple little Bash HTTP server, I hacked a small multimedia server into it:
https://github.com/AdamDanischewski/bashttpd

#!/usr/bin/env bash

#############################################################################
###########################################################################
###                          bashttpd v 1.23
###
### Original author: Avleen Vig,       2012
### Reworked by:     Josh Cartwright,  2012
### Modified by:     A.M.Danischewski, 2015 
### Issues: If you find any issues leave me a comment at 
### http://scriptsandoneliners.blogspot.com/2015/04/bashttpd-self-contained-bash-webserver.html 
### 
### This is a simple Bash based webserver. By default it will browse files and allows for 
### retrieving binary files. 
### 
### It has been tested successfully to view and stream files including images, mp3s, 
### mp4s and downloading files of any type including binary and compressed files via  
### any web browser. 
### 
### Successfully tested on various browsers on Windows, Linux and Android devices (including the 
### Android Smartwatch ZGPAX S8).  
### 
### It handles favicon requests by hardcoded favicon image -- by default a marathon 
### runner; change it to whatever you want! By base64 encoding your favorit favicon 
### and changing the global variable below this header.  
### 
### Make sure if you have a firewall it allows connections to the port you plan to 
### listen on (8080 by default).  
### 
### By default this program will allow for the browsing of files from the 
### computer where it is run.  
###  
### Make sure you are allowed connections to the port you plan to listen on 
### (8080 by default). Then just drop it on a host machine (that has bash) 
### and start it up like this:
###      
### $192.168.1.101> bashttpd -s
###      
### On the remote machine you should be able to browse and download files from the host 
### server via any web browser by visiting:
###      
### http://192.168.1.101:8080 
###      
### This program will generate a micro media server, if you start it with the -m option 
###      
### $192.168.1.101> bashttpd -s -m 
###      
### Afterward source the alias file:  source /tmp/m_player.aliases
### Create a playlist: cd /fav/mp3/collection; 102mpl mp3
### Adds 10 mp3 files are added to the playlist.  
### 
### You should be able to loop stream the content on vlc by opening the url (mrl)  
### and hitting repeat song loop, each time it loops a the next track will be served.  
###  
### On the remote machine you should be able to use vlc to play the media, copy the   
### url (e.g. from notepad) and then paste it into an empty playlist in vlc        
### e.g. C-x-C-c http://192.168.1.101:8080/tmp/lnk.mp4  
###  
### Note: This does not work for Windows media player under its default configuration  
###       because wmp caches the files locally and does not refetch automatically. 
###       If you find a workaround, contact me at scriptsandoneliners.blogspot.com.   
###  
#### This program requires (to work to full capacity) by default: 
### socat or netcat (w/ '-e' option - on Ubuntu netcat-traditional)
### tree - useful for pretty directory listings 
### If you are using socat, you can type: bashttpd -s  
### 
### to start listening on the LISTEN_PORT (default is 8080), you can change 
### the port below.  
###  E.g.    nc -lp 8080 -e ./bashttpd ## <-- If your nc has the -e option.   
###  E.g.    nc.traditional -lp 8080 -e ./bashttpd 
###  E.g.    bashttpd -s  -or- socat TCP4-LISTEN:8080,fork EXEC:bashttpd
### 
### Copyright (C) 2012, Avleen Vig <avleen@gmail.com>
### 
### Permission is hereby granted, free of charge, to any person obtaining a copy of
### this software and associated documentation files (the "Software"), to deal in
### the Software without restriction, including without limitation the rights to
### use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
### the Software, and to permit persons to whom the Software is furnished to do so,
### subject to the following conditions:
### 
### The above copyright notice and this permission notice shall be included in all
### copies or substantial portions of the Software.
### 
### THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
### IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
### FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
### COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
### IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
### CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
### 
###########################################################################
#############################################################################

  ### CHANGE THIS TO WHERE YOU WANT THE CONFIGURATION FILE TO RESIDE 
declare -r BASHTTPD_CONF="/tmp/bashttpd.conf"

  ### CHANGE THIS TO WHERE YOU WANT THE MEDIA DAEMON TO RESIDE
  ### This is optional, only if you want to broadcast a media collection 
  ### to e.g. vlc or any other streaming media player, simply add the media 
  ### file and put your player on loop (the same track, yet it will change the 
  ### the content automagically).    
declare -r MEDIA_DAEMON="/tmp/m_play.bsh"
declare -r M_ALIASES="/tmp/m_player.aliases"
declare -r M_LNK="/tmp/lnk.mp4"  ## The mp4 extension works in vlc for both mp3/mp4 files.    
declare -r M_DIR=""               ## Default dir for media in playlist 
                                  ## w/out abs paths (defaults to pwd).   
declare -r M_PLAYLIST="/tmp/_mpl.txt" 
declare -i M_SLEEP=30  ### How long to wait to check if tracks are being played/pulled.  
declare -r M_PID="/tmp/_mpl_pid_" 

function exit_gracefully() { 
 if [[ -f "${M_PID}_$$" ]]; then  
  IFS=$(echo -en "\n\b") && for a in $(< "${M_PID}_$$"); do 
    echo "Killing media server with pid $a"; 
    ps -ef | grep -i "${MEDIA_DAEMON}" | grep "$a" | awk "{print $2}" | xargs -I {} kill -9 {}; 
  done 
  rm "${M_PID}_$$" 
 fi 
 rm -f "${MEDIA_DAEMON}" 
 exit 0 
}
trap "{ exit_gracefully; }" EXIT SIGINT SIGHUP SIGQUIT SIGTERM 

  ### CHANGE THIS IF YOU WOULD LIKE TO LISTEN ON A DIFFERENT PORT 
declare -i LISTEN_PORT=8080  

 ## If you are on AIX, IRIX, Solaris, or a hardened system redirecting 
 ## to /dev/random will probably break, you can change it to /dev/null.  
declare -a DISCARD_DEV="/dev/random" 
  
 ## Just base64 encode your favorite favicon and change this to whatever you want.    
declare -r FAVICON="AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAADg4+3/srjc/5KV2P+ortn/xMrj/6Ch1P+Vl9f/jIzc/3572f+CgNr/fnzP/3l01f+Ih9r/h4TZ/8fN4//P1Oj/3uPr/7O+1v+xu9X/u8XY/9bi6v+UmdD/XV26/3F1x/+GitT/VVXC/3x/x/+HjNT/lp3Z/6633f/E0eD/2ePr/+bt8v/U4+v/0uLp/9Xj6//Z5e3/oKbX/0pJt/9maML/cHLF/3p8x//T3+n/3Ofu/9vo7//W5Oz/0uHq/9zn7f/j6vD/1OLs/8/f6P/R4Oj/1OPr/7jA4f9KSbf/Skm3/3p/yf/U4ez/1ePq/9rn7//Z5e3/0uHp/87e5//a5Ov/5Ovw/9Hf6v/T4uv/1OLp/9bj6/+kq9r/Skq3/0pJt/+cotb/zdnp/9jl7f/a5u//1+Ts/9Pi6v/O3ub/2uXr/+bt8P/Q3un/0eDq/9bj7P/Z5u7/r7jd/0tKt/9NTLf/S0u2/8zW6v/c5+//2+fv/9bj6//S4un/zt3m/9zm7P/k7PD/1OPr/9Li7P/V5Oz/2OXt/9jl7v+HjM3/lZvT/0tKt/+6w+L/2ebu/9fk7P/V4+v/0uHq/83d5v/a5ev/5ezw/9Pi6v/U4+z/1eXs/9bj6//b5+//vsjj/1hYvP9JSLb/horM/9nk7P/X5e3/1eTs/9Pi6v/P3uf/2eXr/+Tr7//O3+n/0uLr/9Xk7P/Y5e3/w8/k/7XA3/9JR7f/SEe3/2lrw//G0OX/1uLr/9Xi7P/T4ev/0N/o/9zn7f/k7PD/zN3p/8rd5v/T4ur/1ePt/5We0/+0w9//SEe3/0pKt/9OTrf/p7HZ/7fD3//T4uv/0N/o/9Hg6f/d5+3/5ezw/9Li6//T4uv/2ubu/8PQ5f9+hsr/ucff/4eOzv+Ei8z/rLja/8zc6P/I1+b/0OLq/8/f6P/Q4Oj/3eft/+bs8f/R4On/0+Lq/9Tj6v/T4Ov/wM7h/9Df6f/M2uf/z97q/9Dg6f/Q4On/1OPr/9Tj6//S4ur/0ODp/93o7f/n7vH/0N/o/8/f5//P3+b/2OXt/9zo8P/c6fH/zdjn/7fB3/+3weD/1eLs/9nn7//V5Oz/0+Lr/9Pi6//e6O7/5u3x/9Pi6v/S4en/0uLp/9Tj6//W4+v/3Ojw/9rm7v9vccT/wcvm/9rn7//X5Oz/0uHq/9Hg6f/S4er/3uju/+bt8f/R4On/0uHp/9Xk6//Y5u7/1OTs/9bk7P/W5Ov/XFy9/2lrwf/a5+//1uPr/9Pi6v/U4er/0eHq/93o7v/v8vT/5ezw/+bt8f/o7vL/6e/z/+jv8v/p7/L/6e/y/9XZ6//IzOX/6e7y/+nv8v/o7vL/5+7x/+ft8f/r8PP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" 
              
declare -i DEBUG=1 
declare -i VERBOSE=0
declare -a REQUEST_HEADERS
declare    REQUEST_URI="" 
declare -a HTTP_RESPONSE=(
   [200]="OK"
   [400]="Bad Request"
   [403]="Forbidden"
   [404]="Not Found"
   [405]="Method Not Allowed"
   [500]="Internal Server Error")
declare DATE=$(date +"%a, %d %b %Y %H:%M:%S %Z")
declare -a RESPONSE_HEADERS=(
      "Date: $DATE"
   "Expires: $DATE"
    "Server: Slash Bin Slash Bash"
)

function warn() { ((${VERBOSE})) && echo "WARNING: $@" >&2; }

function chk_conf_file() { 
[ -r "${BASHTTPD_CONF}" ] || {
   cat >"${BASHTTPD_CONF}" <<'EOF'
#
# bashttpd.conf - configuration for bashttpd
#
# The behavior of bashttpd is dictated by the evaluation
# of rules specified in this configuration file.  Each rule
# is evaluated until one is matched.  If no rule is matched,
# bashttpd will serve a 500 Internal Server Error.
#
# The format of the rules are:
#    on_uri_match REGEX command [args]
#    unconditionally command [args]
#
# on_uri_match:
#   On an incoming request, the URI is checked against the specified
#   (bash-supported extended) regular expression, and if encounters a match the
#   specified command is executed with the specified arguments.
#
#   For additional flexibility, on_uri_match will also pass the results of the
#   regular expression match, ${BASH_REMATCH[@]} as additional arguments to the
#   command.
#
# unconditionally:
#   Always serve via the specified command.  Useful for catchall rules.
#
# The following commands are available for use:
#
#   serve_file FILE
#     Statically serves a single file.
#
#   serve_dir_with_tree DIRECTORY
#     Statically serves the specified directory using 'tree'.  It must be
#     installed and in the PATH.
#
#   serve_dir_with_ls DIRECTORY
#     Statically serves the specified directory using 'ls -al'.
#
#   serve_dir  DIRECTORY
#     Statically serves a single directory listing.  Will use 'tree' if it is
#     installed and in the PATH, otherwise, 'ls -al'
#
#   serve_dir_or_file_from DIRECTORY
#     Serves either a directory listing (using serve_dir) or a file (using
#     serve_file).  Constructs local path by appending the specified root
#     directory, and the URI portion of the client request.
#
#   serve_static_string STRING
#     Serves the specified static string with Content-Type text/plain.
#
# Examples of rules:
#
# on_uri_match '^/issue$' serve_file "/etc/issue"
#
#   When a client's requested URI matches the string '/issue', serve them the
#   contents of /etc/issue
#
# on_uri_match 'root' serve_dir /
#
#   When a client's requested URI has the word 'root' in it, serve up
#   a directory listing of /
#
# DOCROOT=/var/www/html
# on_uri_match '/(.*)' serve_dir_or_file_from "$DOCROOT"
#   When any URI request is made, attempt to serve a directory listing
#   or file content based on the request URI, by mapping URI's to local
#   paths relative to the specified "$DOCROOT"
#

#unconditionally serve_static_string 'Hello, world!  You can configure bashttpd by modifying bashttpd.conf.'
DOCROOT=/
on_uri_match '/(.*)' serve_dir_or_file_from 

# More about commands:
#
# It is possible to somewhat easily write your own commands.  An example
# may help.  The following example will serve "Hello, $x!" whenever
# a client sends a request with the URI /say_hello_to/$x:
#
# serve_hello() {
#    add_response_header "Content-Type" "text/plain"
#    send_response_ok_exit <<< "Hello, $2!"
# }
# on_uri_match '^/say_hello_to/(.*)$' serve_hello
#
# Like mentioned before, the contents of ${BASH_REMATCH[@]} are passed
# to your command, so its possible to use regular expression groups
# to pull out info.
#
# With this example, when the requested URI is /say_hello_to/Josh, serve_hello
# is invoked with the arguments '/say_hello_to/Josh' 'Josh',
# (${BASH_REMATCH[0]} is always the full match)
EOF
   warn "Created bashttpd.conf using defaults.  Please review and configure bashttpd.conf before running bashttpd again."
#  exit 1
} 
}

function gen_media_daemon() { 
cat <<EOF > "${MEDIA_DAEMON}" 
#!/usr/bin/env bash 

declare -r m_lnk="${M_LNK}"
declare -r m_dir="${M_DIR:-$(pwd)}" 
declare -r m_playlist="${M_PLAYLIST}" 
 ## Sleep in case streams aren't being pulled, should be shorter than your shortest media. 
declare -i m_sleep=${M_SLEEP} 
declare -i m_count=0  ## Total playlist entries. 
declare -i m_track=1  ## Current track selection. 
while :; do  
if lsof "\${m_lnk}" 2>"${DISCARD_DEV}" | { grep -q "\${m_lnk##*/}"; } || [[ ! -f "\${m_lnk}" ]]; then  
 if [[ -f "\${m_playlist}" ]] && m_count=\$(wc -l <"\${m_playlist}") && ((\${m_count} > 0));  then   
  ((\${m_track}>\${m_count})) && m_track=1       ## Reset to first track if track selection is over.  
  song=\$(sed -n \${m_track}p "\${m_playlist}")  ## Very minor race condition. 
  song_l="\${#song}" 
  np_song_l="\${song##*/}" 
  (( \${#np_song_l} == \${song_l} )) && song="\${m_dir}/\${song}" 
  while :; do 
     ## Hack idea: echo the to be cp'd song name to a tmp file, store it in a global and add a new alias 
     ## to display the current playing track listing. Make it yours! =)     
   lsof "\${m_lnk}" 2>"${DISCARD_DEV}" | { ! grep -q "\${m_lnk##*/}"; } && 
   [[ -f "\${song}" ]] && { rm -f "\${m_lnk}"; cp "\${song}" "\${m_lnk}"; break; } || sleep 1; 
  done   
  m_track+=1
 else 
  sleep \${m_sleep} ## No playlist. 
 fi
else 
 sleep 2 ## No stream being pulled. 
fi 
done 
EOF
chmod +x "${MEDIA_DAEMON}"
}

function recv() { ((${VERBOSE})) && echo "< $@" >&2; }

function send() { ((${VERBOSE})) && echo "> $@" >&2; echo "$*"; }

function add_response_header() { RESPONSE_HEADERS+=("$1: $2"); }

function send_response_binary() {
 local code="${1}"
 local file="${2}" 
 local transfer_stats="" 
 local tmp_stat_file="/tmp/_send_response_$$_"
 send "HTTP/1.0 $1 ${HTTP_RESPONSE[$1]}"
 for i in "${RESPONSE_HEADERS[@]}"; do
    send "$i"
 done
 send
 if ((${VERBOSE})); then 
   ## Use dd since it handles null bytes
  dd 2>"${tmp_stat_file}" < "${file}" 
  transfer_stats=$(<"${tmp_stat_file}") 
  echo -en ">> Transferred: ${file}\n>> $(awk '/copied/{print}' <<< "${transfer_stats}")\n" >&2  
  rm "${tmp_stat_file}"
 else 
   ## Use dd since it handles null bytes
  dd 2>"${DISCARD_DEV}" < "${file}"   
 fi 
}   

function send_response() {
  local code="$1"
  send "HTTP/1.0 $1 ${HTTP_RESPONSE[$1]}"
  for i in "${RESPONSE_HEADERS[@]}"; do
     send "$i"
  done
  send
  while IFS= read -r line; do
     send "${line}"
  done
}

function send_response_ok_exit() { send_response 200; exit 0; }

function send_response_ok_exit_binary() { send_response_binary 200  "${1}"; exit 0; }

function fail_with() { send_response "$1" <<< "$1 ${HTTP_RESPONSE[$1]}"; exit 1; }

function serve_file() {
  local file="$1"
  local CONTENT_TYPE=""
  case "${file}" in
    *\.css)
      CONTENT_TYPE="text/css"
      ;;
    *\.js)
      CONTENT_TYPE="text/javascript"
      ;;
    *)
      CONTENT_TYPE=$(file -b --mime-type "${file}")
      ;;
  esac
  add_response_header "Content-Type"  "${CONTENT_TYPE}"
  CONTENT_LENGTH=$(stat -c'%s' "${file}") 
  add_response_header "Content-Length" "${CONTENT_LENGTH}"
    ## Use binary safe transfer method since text doesn't break. 
  send_response_ok_exit_binary "${file}"
}

function serve_dir_with_tree() {
  local dir="$1" tree_vers tree_opts basehref x
    ## HTML 5 compatible way to avoid tree html from generating favicon
    ## requests in certain browsers, such as browsers in android smartwatches. =) 
  local no_favicon=" <link href=\"data:image/x-icon;base64,${FAVICON}\" rel=\"icon\" type=\"image/x-icon\" />"  
  local tree_page="" 
  local base_server_path="/${2%/}"
  [ "$base_server_path" = "/" ] && base_server_path=".." 
  local tree_opts="--du -h -a --dirsfirst" 
  add_response_header "Content-Type" "text/html"
   # The --du option was added in 1.6.0.   "/${2%/*}"
  read _ tree_vers x < <(tree --version)
  tree_page=$(tree -H "$base_server_path" -L 1 "${tree_opts}" -D "${dir}")
  tree_page=$(sed "5 i ${no_favicon}" <<< "${tree_page}")  
  [[ "${tree_vers}" == v1.6* ]] 
  send_response_ok_exit <<< "${tree_page}"  
}

function serve_dir_with_ls() {
  local dir="${1}"
  add_response_header "Content-Type" "text/plain"
  send_response_ok_exit < \
     <(ls -la "${dir}")
}

function serve_dir() {
  local dir="${1}"
   # If `tree` is installed, use that for pretty output.
  which tree &>"${DISCARD_DEV}" && \
     serve_dir_with_tree "$@"
  serve_dir_with_ls "$@"
  fail_with 500
}

function urldecode() { [ "${1%/}" = "" ] && echo "/" ||  echo -e "$(sed 's/%\([[:xdigit:]]\{2\}\)/\\\x\1/g' <<< "${1%/}")"; } 

function serve_dir_or_file_from() {
  local URL_PATH="${1}/${3}"
  shift
  URL_PATH=$(urldecode "${URL_PATH}") 
  [[ $URL_PATH == *..* ]] && fail_with 400
   # Serve index file if exists in requested directory
  [[ -d "${URL_PATH}" && -f "${URL_PATH}/index.html" && -r "${URL_PATH}/index.html" ]] && \
     URL_PATH="${URL_PATH}/index.html"
  if [[ -f "${URL_PATH}" ]]; then
     [[ -r "${URL_PATH}" ]] && \
        serve_file "${URL_PATH}" "$@" || fail_with 403
  elif [[ -d "${URL_PATH}" ]]; then
     [[ -x "${URL_PATH}" ]] && \
        serve_dir  "${URL_PATH}" "$@" || fail_with 403
  fi
  fail_with 404
}

function serve_static_string() {
  add_response_header "Content-Type" "text/plain"
  send_response_ok_exit <<< "$1"
}

function on_uri_match() {
  local regex="$1"
  shift
  [[ "${REQUEST_URI}" =~ $regex ]] && \
     "$@" "${BASH_REMATCH[@]}"
}

function unconditionally() { "$@" "$REQUEST_URI"; }

function gen_playlist_aliases() { 
 [[ -f "${M_ALIASES}" ]] && rm -f "${M_ALIASES}" 
 echo "alias add2mpl='_() { song_l=\"\${#1}\"; np_song_l=\"\${1##*/}\"; [[ ! \${#np_song_l} -lt \${song_l} ]] && song=\"\$(pwd)/\${1}\" || song=\"\${1}\"; echo \"\${song}\" >> \"${M_PLAYLIST}\"; }; _'" >> "${M_ALIASES}" 
 echo "alias rmmpl='rm \"${M_PLAYLIST}\"'" >> "${M_ALIASES}"
 echo "alias lsmpl='cat \"${M_PLAYLIST}\"'" >> "${M_ALIASES}"
 echo "alias 102mpl='_() { IFS=\$(echo -en \"\n\b\") && for a in \$(ls -f1 *\"\${1}\" | shuf | tail -10); do add2mpl \"\${a}\"; done; }; _'" >> "${M_ALIASES}"
 echo "alias rempl='rmmpl; 102mpl'" >> "${M_ALIASES}"
 echo "echo -e \"\\nThe following aliases allow for tracks to be added and removed from the playlist: \\n\"" >> "${M_ALIASES}"
 echo "echo \"     alias add2mpl: Adds a new media track to the current playlist\""  >> "${M_ALIASES}"
 echo "echo \"     alias   rmmpl: Deletes the current playlist\""  >> "${M_ALIASES}"
 echo "echo \"     alias   lsmpl: Lists the current playlist\""  >> "${M_ALIASES}"
 echo "echo -e \"     alias   rempl: Recreates the current playlist with 10 random tracks, you may provide \\n                    an optional filter arg.\""  >> "${M_ALIASES}"
 echo "echo -e \"     alias  102mpl: Adds 10 random tracks from the current directory to the current playlist.\""  >> "${M_ALIASES}"
 echo "echo -e \"      Optionally you may provide a filter argument (mp4,avi,mp3  etc), to add 10 random \\n      mp3 tracks from current dir to the current playlist: e.g. $> 102mpl mp3 \\n\""  >> "${M_ALIASES}"
 echo "echo -e \"Now just add some tracks and you're ready to start vlc on a remote machine: \\n e.g. \\\$> vlc \\\"http://192.168.1.101:8080/tmp/lnk.mp4\\\"\""  >> "${M_ALIASES}"
 echo "echo \"Put vlc on single song loop, all playlist tracks should play through looping the entire playlist.\""  >> "${M_ALIASES}"
 echo "echo -e \"Hint: To skip a song, hit stop on vlc after at least 2 seconds then play.\\n\""  >> "${M_ALIASES}"
 chmod +x "${M_ALIASES}"
}  
 
function start_media_daemon() { 
 [[ ! -f "${MEDIA_DAEMON}" ]] && gen_media_daemon && echo "Created media daemon config file.."  
 [[ ! -f "${MEDIA_DAEMON}" ]] && echo "Error: No media daemon script found, wanted: $MEDIA_DAEMON" && exit 0 
 gen_playlist_aliases
 rm -f "${M_LNK}"
 echo "You can add media to the playlist with the following aliases .."
 "${M_ALIASES}"
 echo "You can source the aliases file from other terminals with: \$> source \"${M_ALIASES}\" "
 echo "Starting media daemon.."  && "${MEDIA_DAEMON}" &  
 echo "$!" >> "${M_PID}_$$" 
} 

function main() { 
 local recv="" 
 local line="" 
 local REQUEST_METHOD=""
 local REQUEST_HTTP_VERSION="" 
 chk_conf_file
 [[ ${UID} = 0 ]] && warn "It is not recommended to run bashttpd as root."
  # Request-Line HTTP RFC 2616 $5.1
 read -r line || fail_with 400
 line=${line%%$'\r'}
 recv "${line}"
 read -r REQUEST_METHOD REQUEST_URI REQUEST_HTTP_VERSION <<< "${line}"
 [ -n "${REQUEST_METHOD}" ] && [ -n "${REQUEST_URI}" ] && \
  [ -n "${REQUEST_HTTP_VERSION}" ] || fail_with 400
  # Only GET is supported at this time
 [ "${REQUEST_METHOD}" = "GET" ] || fail_with 405
 while IFS= read -r line; do
   line=${line%%$'\r'}
   recv "${line}"
     # If we've reached the end of the headers, break.
   [ -z "${line}" ] && break
   REQUEST_HEADERS+=("${line}")
 done
} 

[[ ! -z "${2}" ]]  && [[ "${2}" = "-m" ]] && start_media_daemon

if [[ ! -z "${1}" ]] && [ "${1}" = "-s" ]; then 
 socat TCP4-LISTEN:${LISTEN_PORT},fork EXEC:"${0}"  2>"${DISCARD_DEV}" 
 M_SEM=0 
else 
 main 
 source "${BASHTTPD_CONF}" 
 fail_with 500
fi 

Offline

#3016 2017-05-24 21:53:23

bulletmark
Member
From: Brisbane, Australia
Registered: 2013-10-22
Posts: 675

Re: Post your handy self made command line utilities

adam_danischewski wrote:

Here is a simple little Bash HTTP server ..

Not as simple as:

python -m http.server

Offline

#3017 2017-05-25 10:36:57

adam_danischewski
Banned
Registered: 2016-05-06
Posts: 23
Website

Re: Post your handy self made command line utilities

bulletmark wrote:

Not as simple as:

python -m http.server

That's not nearly as functional as the web server I posted, did you actually try playing around with it? It serves files out of the box and is very extendable, you can write your own rule sets for it, and there is a working media server. Name it bashttpd.bsh and start it up ($> bashttpd.bsh -s -m) and open your browser to http://<your ip>:8080

You should see a directory tree listing, browse to a directory where you have an mp4/webm file and click on it and watch it stream in your web browser. Those standard little web servers aren't very functional, good for testing if you really need to test something simple. The web server I posted can be uploaded to any shell account and when run can allow for downloading and streaming of the remote files.

Furthermore, it looks like there is no http.server in the standard Python library.
$>  python -m http.server
/usr/bin/python: No module named http

If you want a webserver that already likely exists (if you have Php installed) doesn't really do anything you can use: 

php -S localhost:8000 -t /

Last edited by adam_danischewski (2017-05-25 10:37:52)

Offline

#3018 2017-05-25 11:16:23

bulletmark
Member
From: Brisbane, Australia
Registered: 2013-10-22
Posts: 675

Re: Post your handy self made command line utilities

adam_danischewski wrote:

Furthermore, it looks like there is no http.server in the standard Python library.
$>  python -m http.server
/usr/bin/python: No module named http

You're not running Arch.

Offline

#3019 2017-05-25 12:19:10

adam_danischewski
Banned
Registered: 2016-05-06
Posts: 23
Website

Re: Post your handy self made command line utilities

bulletmark wrote:

You're not running Arch.

I run Arch on one laptop yet responded from another. It works on my Arch Linux laptop - that's kind of irrelevant to the point though since it needs software that is not default installed with Python.

While it may be fine to run from an Arch install if you only need listings/downloads. By default it is auto-jailed to the directory where it is run. 

The script I posted can be uploaded anywhere and function, then you can use your Archlinux installation to access all data that you have permissions on. It is defaulted to socat, yet can be modified to use netcat. If a webhost doesn't have Arch (likely) then getting http.server installed for Python may be difficult. It also has a media streaming server, judging from your responses you probably haven't spent much time playing around with it - this Bash httpd is small and provides more functionality and capabilities than the default Python webserver provides.

Offline

#3020 2017-05-25 12:28:38

Alad
Wiki Admin/IRC Op
From: Bagelstan
Registered: 2014-05-04
Posts: 2,418
Website

Re: Post your handy self made command line utilities

bulletmark wrote:
adam_danischewski wrote:

Here is a simple little Bash HTTP server ..

Not as simple as:

python -m http.server

Might as well run apache at that point, because it's "simple". Or darkhttpd, or anything else - it doesn't contribute in the least to the script that was posted or this thread. Nor is making accusations on what people run since this is not a support thread.

Back on-topic, you need to run it through shellcheck since there are a few dozen warnings. Also look at: https://github.com/dualbus/bashly/blob/ … ttp.bashly

Last edited by Alad (2017-05-25 12:32:07)


Mods are just community members who have the occasionally necessary option to move threads around and edit posts. -- Trilby

Offline

#3021 2017-05-25 15:08:34

adam_danischewski
Banned
Registered: 2016-05-06
Posts: 23
Website

Re: Post your handy self made command line utilities

Alad wrote:

Back on-topic, you need to run it through shellcheck since there are a few dozen warnings. Also look at: https://github.com/dualbus/bashly/blob/ … ttp.bashly

I checked the warnings quick on https://www.shellcheck.net, it looks like somehow DISCARD_DEV was declared as an array, just remove the "-a" on it. As for the alias generation, it should probably be a cat << EOF type of thing, except it becomes complicated by the single quotes and need to expand variables. I'm not sure about the arguments against "$@" they expand fine in strings vs. "$*". The arithmetic checks on values are bit questionable - I'm not sure there is a better way for those. So I'm going to leave it alone for now, it works well and it's meant/hoped to be hacked so I'll leave the improving to those are interested.

The bashly idea looks like it had some promise, but it hasn't been updated in over 3 years and trying to fire it up quick involved a little bit too much effort for me at the moment.

Offline

#3022 2017-05-25 15:15:15

adam_danischewski
Banned
Registered: 2016-05-06
Posts: 23
Website

Re: Post your handy self made command line utilities

Useful script to rename any troubly named file:

#!/usr/bin/env bash 
#set -x 
#############################################################################
###########################################################################
### Created by Adam Danischewski (c) 2014 v1.01
### Issues: If you find any issues emai1 me at my <first name> dot 
###         <my last name> at gmail dot com.  
### This program handles the following known filename problems: 
         ###  Spaces anywhere incl the begin/end of filenames ==> _'s 
         ###  Newlines embedded filenames               ==> RANDOM hexchar a-f0-9
         ###  Multibyte Characters of any encoding type ==> RANDOM hexchar a-f0-9 
         ###  Backslashes are replaced                  ==> RANDOM hexchar a-f0-9  
         ###  Other special characters in filenames     ==> RANDOM hexchar a-f0-9
              ### Although leading dashes are technically legal they 
              ### can cause a lot of problems if you don't expect them 
         ###  Leading dashes in filenames               ==> RANDOM hexchar a-f0-9                
    ##This program is free software: you can redistribute it and/or modify
    ##it under the terms of the GNU General Public License as published by
    ##the Free Software Foundation, either version 3 of the License, or
    ##(at your option) any later version.

    ##This program is distributed in the hope that it will be useful,
    ##but WITHOUT ANY WARRANTY; without even the implied warranty of
    ##MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ##GNU General Public License for more details.

    ##You should have received a copy of the GNU General Public License
    ##along with this program.  If not, see <http://www.gnu.org/licenses/>.
###########################################################################
#############################################################################

declare -r  DATE_PREFIX=$(date +%Y%m%d)
declare -r  RENAME_BSH=".rename_${DATE_PREFIX}_$$.bsh"   
declare -r  UNRENAME_BSH=".unrename_${DATE_PREFIX}_$$.bsh"   
declare -i  MAXBADCHRS=150 
declare -i  WROTE_ENTRIES=0
declare -r  VIEWLOGPROG="$(which geany || echo 'cat')"
declare -i  AUTOVIEWLOG=1
declare -i  AUTOEXECUTE=0
declare -r  DEFPERM=400 
declare -i  QUIETMODE=0 
declare -i  DEBUGMODE=0
declare     MVOPTIONS="-nv"  
declare     CPOPTIONS="-nv"  
declare     SENTINELS=""
#declare -r  ECHOCMD="stdbuf -o0 echo"
#declare -r  ECHOCMD="unbuffer echo"

function usage() {
cat <<EOF
Usage: ${0##*/} <-h> <-v=[on|off]> <-t|d|x|q|s> <-c=[numchars]>

OPTIONS:
      -h           Show this message
      -d           Turn on debug mode 
      -v=<on|off>  Turn on/off auto review of rename file. <default is on> 
      -t           Automatically tests the functionality on known troubly 
                   named files and reports if this program is working properly.  
      -q|-s        Quiet/Silent mode - don't report much if anything
      -c=<num>     Sets the max number of bad characters to replace (default=150)           
      -x           "eXpert/eXpress/eXecute" mode -- it will chmod +x and 
                   automatically execute the generated rename script. 
                   This option is not recommended for sensitive data areas.
EOF
} 
 
function help() {
cat <<EOF
Description: ${0##*/}

This program will create scripts to rename all files with special 
characters in the directory where it is run. It replaces spaces with 
_'s and really bad characters with random characters. 

The scripts by default are named: .rename_<date>_<pid>.bsh and
.unrename_<date>_<pid>.bsh. It is recommended that you review them both
to make sure everything is okay and reversible before you run them. The
default permissions set are 400 so you usually need to chmod the files
before running them (e.g. chmod +x ./.rename_<date>_<pid>.bsh) 
EOF

usage 

cat <<EOF
  E.g.
      \$cd /directory/where/bad/files/live 
      \$${0##*/} 
      \$chmod + .rename_<date>_<pid>.bsh
           ... review files ...  
      \$bash ./.rename_<date>_<pid>.bsh 
EOF
exit 0 
}

function fail_test() { 
 echo "$2" 
 #echo -en "$2" | tee >(cat - >&2) 1>/dev/null
 echo "Unit Testing of ${0##*/} FAILED.. " 
 echo "It is not recommended to use this program until you find out why.. " 
 exit $1 
} 

  ## <arg 1> string - string to build random chr from 
function get_random_chr() { 
 local    BUILDSTR="$1"
 local    MD5STR="$(md5sum <<< "$BUILDSTR")" 
 local -i INDEX=$(($RANDOM%9))
 echo "${MD5STR:$INDEX:1}"
}  

  ## <arg 1> string - string to build random chr from 
function get_random_sentinel() { 
 local    BUILDSTR="$1"
 local    MD5STR="$(md5sum <<< "$BUILDSTR")" 
 local -i INDEX=$(($RANDOM%9))
 local    TMPSENTINEL="${MD5STR:$INDEX:3}"
   ### Loop until we know the string is a unique sentinel for our string
 while :; do 
  CHCK="$(grep -o "$TMPSENTINEL" <<< "${BUILDSTR}${SENTINELS}")"
  if [[ -z "$CHCK" ]]; then 
    break;
  else 
    MD5STR="$(md5sum <<< "$(get_random_chr "${MD5STR}")${MD5STR}")" 
    TMPSENTINEL="${MD5STR:$INDEX:3}" 
  fi 
 done 
 echo "${TMPSENTINEL}" 
}  

  #arg <1> string - a filename to test 
function unit_test() {   
 #set -x 
 local FILENAMEFROMHELL="$1" 
 local OK=1 
 TESTDIR="/tmp/_${0##*/}_test_$$_" 
 mkdir -p "$TESTDIR" 
 if [[ -d "$TESTDIR" ]]; then 
    cd "$TESTDIR"
 else 
    echo "Test directory does not exist.. " 
    fail_test -3 
 fi    
 touch "${FILENAMEFROMHELL}"  
 [[ ! -f "$FILENAMEFROMHELL" ]] && fail_test -4 "Cant find test file.. " 
 ${0##./} -v=off -x 
 ((! ! $?)) && fail_test -7 "Cant find this prog from test loc, put this prog in your path or use a FQN (/abs/toprog).. " 
 chmod +x ./.*name*
 [[ -f "$FILENAMEFROMHELL" ]] && fail_test -5 "Test file not renamed.. "
 echo "Successfully renamed trouble file ... " 
 ./.unrename*
 [[ ! -f "$FILENAMEFROMHELL" ]] && fail_test -6 "Test file not unrenamed.. " 
 echo "Successfully unrenamed trouble file ... " 
 cd - 
 rm -f "${TESTDIR}/."* 2>/dev/null 
 rm -f "${TESTDIR}/"* 2>/dev/null 
 rmdir "${TESTDIR}"
 ((! ! $?)) && fail_test -8 "Could not delete test directory ${TESTDIR}"  
 echo "Testing of ${0##*/} Successful!! " 
 return 0 
}

function test_fire() { 
  ## leading $'s, multiple backslashes, multiple newlines, multiple multibyte characters and trailing spaces
FNHORROR1=$(echo '$$th\\\\\\SSS\\#$(*&@isNNN # is !#\\\\#!$SSS#@*()&这NNN个程序\\\\\\是体SSS面^$%a NNNfile \\\\\  ' | sed "s/NNN/\xa/g" | sed "s/SSS/\'/")	
unit_test "$FNHORROR1" 
  ## leading space, multiple backslashes, multibyte characters and newlines with a trailing backslash 
FNHORROR2=$(echo ' \$$th\\\\\\SSS\\#$(*&@isNNN # is !#\\\\#!$\SSS#@*()&这NNN个程序\\\\\\是体SSS面^$%a NNNfile \\\\\ BACK' | sed "s/NNN/\xa/g" | sed "s/SSS/\'/" | sed "s/BACK/\x5c/")	
unit_test "$FNHORROR2" 
echo "This program should work as expected (at least where it was run).. " 
exit 0 
} 

function process_options() { 
local OPTIND OPTARG OPTION h t v q s d c
#read -p "inside process options OPTARG is $OPTARG " -u 1 bbbb
while getopts “:htqsdc:xv:” OPTION "$@"; 
 do
     case "$OPTION" in
         h)
             help
             ;;
         c)
             OPTVAL="${OPTARG##*=}"
             if [[ ! -z "$(echo "$OPTVAL" | grep "^[0-9]*$")" ]]; then 
               MAXBADCHRS=$OPTVAL 
             else 
               usage
               echo "${0##*/} -c=<num> option $OPTARG is invalid, must be an integer > 0."
               exit 0               
             fi  
             ;;
         t)
             test_fire
             ;;
         x)
             AUTOEXECUTE=1
             ;;
         d)
             DEBUGMODE=1
             ;;
         s)
             :
             ;&
         q)             
             MVOPTIONS="-n"  
             CPOPTIONS="-n"  
             AUTOVIEWLOG=0
             QUIETMODE=1
             ;; 
         v)
             if [ "$OPTARG" == "=off" ]; then 
               AUTOVIEWLOG=0 
             elif [ "$OPTARG" == "=on" ]; then 
               AUTOVIEWLOG=1 
             else 
               echo "${0##*/} -v option $OPTARG is invalid";  
               usage
               exit 0
             fi  
             ;;
         ?)
             usage
             exit 0
             ;;
     esac
done
(($DEBUGMODE)) && set -xuo pipefail
} 

process_options "$@"
 
if [[ ! -f "$RENAME_BSH" ]]; then 
 echo "#!/usr/bin/env bash" > "$RENAME_BSH"
 echo "##### This script was automatically generated by ${0##*/}. #####" >> "$RENAME_BSH" 
 echo "## If the data is sensitive you should review this script for " >> "$RENAME_BSH" 
 echo "## accuracy prior to execution." >> "$RENAME_BSH" 
 echo "## And it is recommended that you keep a copy of this script and the sister"  >> "$RENAME_BSH" 
 echo "## unrename script for your records." >> "$RENAME_BSH" 
 echo "## Commented mv commands are only for readability, they will break so don't use them.." >> "$RENAME_BSH" 
else   
 echo "File already exists $RENAME_BSH not clobbering.. "
 exit -1
fi  

if [[ ! -f "$UNRENAME_BSH" ]]; then 
 echo "#!/usr/bin/env bash" > "$UNRENAME_BSH"
 echo "##### This script was automatically generated by ${0##*/}. #####" >> "$UNRENAME_BSH" 
 echo "## If the data is sensitive you should review this script for " >> "$UNRENAME_BSH" 
 echo "## accuracy prior to execution." >> "$UNRENAME_BSH" 
 echo "## And it is recommended that you keep a copy of this script and its brother"  >> "$UNRENAME_BSH" 
 echo "## rename script for your records." >> "$UNRENAME_BSH" 
 echo "## Commented mv commands are only for readability, they will break so don't use them.." >> "$UNRENAME_BSH" 
else 
 echo "File already exists $UNRENAME_BSH not clobbering.. " 
exit -1  
fi 

while IFS= read -r -d '' a; do 
 ((!$QUIETMODE)) && echo  "Processing $a ..."         
 TMP="$a"
 CHANGED=0 
 for b in $(eval echo "{1..${MAXBADCHRS}}"); do 
    OLDHASH=$(echo "$TMP" | md5sum) 
      ## probably should include way to include wider range of random replacements or a mapping.. switch 
    TMP=$(echo "$TMP" | sed "s/ /_/g;s/[^0-9A-Za-z._-]/$(get_random_chr "${TMP}")/"|tr "\n" "$(get_random_chr "${TMP}")"|sed "s/^[^a-Z0-9._]/$(get_random_chr "${TMP}")/"|sed 's/.$/\n/' | LANG=C sed "s/[\x80-\xFF]/$(get_random_chr "${TMP}")/")           
    NEWHASH=$(echo "$TMP" | md5sum) 
    [ "$OLDHASH" == "$NEWHASH" ] && break; 
    CHANGED=1
 done 
 if (($CHANGED)); then   
  WROTE_ENTRIES=1 
  BACKSLASH="$(get_random_sentinel "$a")"
  SENTINELS="${SENTINELS}${BACKSLASH}" 
  NEWLINE="$(get_random_sentinel "$a")"
  SENTINELS="${SENTINELS}${NEWLINE}" 
  SINGLEQUOTE="$(get_random_sentinel "$a")"
  SENTINELS="${SENTINELS}${SINGLEQUOTE}" 
  NEWFILE=$(sed "s/\x5c\x5c/${BACKSLASH}/g" <<< "$a")
  NEWFILE=$(echo -en "$NEWFILE" | sed ":a;N;\$!ba;s/\n/${NEWLINE}/g" | sed "s/\x27/${SINGLEQUOTE}/g") 
  echo  "##mv ${MVOPTIONS} -- '${NEWFILE}' '${TMP}'"        >> "$RENAME_BSH" 
  echo  "NEWFILE=\$(echo -n '${NEWFILE}'|sed \"s/${NEWLINE}/\xa/g\"|sed \"s/${BACKSLASH}/\x5c/g\"|sed \"s/${SINGLEQUOTE}/\x27/g\")"  >> "$RENAME_BSH" 
  echo  "mv ${MVOPTIONS} -- \"\$NEWFILE\" '${TMP}'"         >> "$RENAME_BSH" 
  echo  "##mv ${MVOPTIONS} -- '${TMP}' '${NEWFILE}'"        >> "$UNRENAME_BSH" 
  echo  "NEWFILE=\$(echo -n '${NEWFILE}'|sed \"s/${NEWLINE}/\xa/g\"|sed \"s/${BACKSLASH}/\x5c/g\"|sed \"s/${SINGLEQUOTE}/\x27/g\")"   >> "$UNRENAME_BSH" 
  echo  "mv ${MVOPTIONS} -- '${TMP}' \"\$NEWFILE\""         >> "$UNRENAME_BSH" 
 fi 
SENTINELS=
done < <(find . -maxdepth 1 ! -name ".rename*" -a ! -name ".unrename*" -a ! -path . -printf "%f\0")

if [[ -f "$UNRENAME_BSH" ]] && [[ -f "$RENAME_BSH" ]] && (($WROTE_ENTRIES)); then 
 chmod ${DEFPERM} "$UNRENAME_BSH" "$RENAME_BSH" 
 ((!$QUIETMODE)) && echo "Done building scripts.. " 
 if ((! $AUTOEXECUTE)); then 
  ((!$QUIETMODE)) && echo "Review $RENAME_BSH and if it looks sane enough, chmod +x and run it" 
     ## Check to see if the filesystem where the scripts are generated is mounted noexec 
  ((!$QUIETMODE)) && mount | awk "\$0 ~ \"$(df . | sed '1d' | awk '{print $1}')\"{if(\$0 ~ "noexec") print \"The filesystem where the rename scripts are located looks like it is\n mounted noexec.\nYou may have to run the scripts by prefixing bash prior to the script.\n  E.g. chmod +x ${RENAME_BSH}; bash ./${RENAME_BSH}\" }"
  (($AUTOVIEWLOG)) && $VIEWLOGPROG "$RENAME_BSH"
 else 
  ((!$QUIETMODE)) && echo "Executing $RENAME_BSH .. " 
  chmod -f +x "$RENAME_BSH"
  bash "$RENAME_BSH" ## call the interpreter outside the script to avoid noexec mounts causing failure to execute
  ((!$QUIETMODE)) && echo "Done!!" 
 fi 
else 
 rm "$UNRENAME_BSH" "$RENAME_BSH" 
 ((!$QUIETMODE)) && echo "Checked files and directories, looks like nothing needs renaming .. " 
fi  

exit 0 

Offline

#3023 2017-05-26 03:32:31

eschwartz
Fellow
Registered: 2014-08-08
Posts: 4,097

Re: Post your handy self made command line utilities

adam_danischewski wrote:
bulletmark wrote:

You're not running Arch.

I run Arch on one laptop yet responded from another. It works on my Arch Linux laptop - that's kind of irrelevant to the point though since it needs software that is not default installed with Python.

In defense of bulletmark, he is entirely correct (in terms of why you got different results).

`python` on Arch Linux is Python 3 and http.server comes bundled with the default distribution. On other distros, `python` would be Python 2.

As for Python 2, http.server is also shipped with the default upstream distribution. Only, in Python 2 it is called SimpleHTTPServer and in Python 3 it was moved to http.server

Also see the Big list of http static server one-liners

...

That being said, a server implemented in pure bash powered by socat is still cool and worthy of being posted to this thread, so party poopers complaining about how many other solutions there are, are missing the point.

Last edited by eschwartz (2017-05-26 04:29:38)


Managing AUR repos The Right Way -- aurpublish (now a standalone tool)

Offline

#3024 2017-05-26 17:50:26

adam_danischewski
Banned
Registered: 2016-05-06
Posts: 23
Website

Re: Post your handy self made command line utilities

If you need to copy things to multiple locations:

alias cpm='_() { src="${1%/}"; shift; printf "\"%s\" " "$@" | xargs -n 1 cp -vR "${src}"; }; _' 

Offline

#3025 2017-05-26 17:54:06

eschwartz
Fellow
Registered: 2014-08-08
Posts: 4,097

Re: Post your handy self made command line utilities

adam_danischewski wrote:

If you need to copy things to multiple locations:

alias cpm='_() { src="${1%/}"; shift; printf "\"%s\" " "$@" | xargs -n 1 cp -vR "${src}"; }; _' 

Why not just use a function "cpm()" directly???


Managing AUR repos The Right Way -- aurpublish (now a standalone tool)

Offline

Board footer

Powered by FluxBB