Useful scripts

aragats

Daemon

Reaction score: 433
Messages: 1,055

(about parts of the command line disappearing)
....
I'm not sure from mind what causes this, come to think of it I suppose it could also be an effect of setting up a specific prompt...
I don't see such thing with ksh93 in urxvt.
ShelLuser , since you use Xorg, have you tried running resize when such things happen?
I noticed that sometimes terminals get screwed up by "bad outputs" of certain commands.
 

ShelLuser

Son of Beastie

Reaction score: 1,669
Messages: 3,511

Thanks for your comments, both of you :)

Out of curiosity, why is ksh your favorite? And which one of the various implementations?
I use shells/pdksh on all my servers, and the 'why' part has everything to do with SunOS / Solaris. There is no rational reasoning other than ksh being the standard on Sun Solaris and that was the very first Unix environment I learned to operate (and I loved every part of it).

Around the 90's during my internship within Olivetti computers did I learn about this 'magical' operating system called Unix which could outperform Windows on every possible geek level. Transporting files between PC's? No need for floppies nor a special parallel cable with laplink or Norton Commander. Instead even a serial cable would do and you'd be able to simply communicate between those machines with nothing other than the Unix OS itself. Even Windows 3.11 couldn't pull that off!

Learned about Linux (RedHat 'Picasso') and dove in head first.

So when I became a sysadmin at my first job and suddenly discovered that a sub-group within our company used a Sun Sparcstation running Sun Solaris ("Unix") plus Smartstream (database server) while they were having issues I knew exactly what to do. Well, I didn't but I knew man man, learned about catman and then apropos then and there. Fixed the network hiatus by switching the server from DHCP client (provided by a flakey Novell server) to a static IP and everyone was happy. So happy that I was sent onto 2 Sun Solaris training camps, paid for by said company. That was the beginning of the end ;)

I didn't switch from Linux to FreeBSD, I switched from Solaris 10/x86 to FreeBSD :)

Back then (around 2009 I think?) FreeBSD was the perfect Solaris replacement for me; UFS & ZFS, Jails vs. Zones, ipf (Solaris firewall) and a sane user land.

I exchanged ipfilter for pf last year or so, but I'm still a die hard Korn shell user ;)

Note that I don't use it for scripting or such, only interaction. Mine even runs in vi mode by default, I love it:

Code:
peter@zefiris:/home/peter $ cat .kshrc
if [ "`basename ${0#-}`" == "ksh" ]; then
   set -o posix -o braceexpand -o vi -o vi-tabcomplete;
   PS1="`whoami`@`hostname -s`:\${PWD} \$ ";
fi
Very important detail is that for me it's not only about work, I also actually enjoy working with this stuff.

I really should change my PS1 sometime, these days you can swap out your home for ~ or make it cut longer pathlines into smaller bits but I never took the time to do so and just kept using what I already had & once learned :)

Sorry for a brief ramble there, but yah ;)

ShelLuser , since you use Xorg, have you tried running resize when such things happen?
I noticed that sometimes terminals get screwed up by "bad outputs" of certain commands.
No, never bothered with resize(1) (did look it up as you can tell ;) ). But this has nothing to do with X directly though, this also happens if I'm on a regular console (I never automatically log onto the GUI).

But it's shell related. As olli@ mentioned above; this doesn't happen with sh (which I also tried) but more so with ksh. Still, it doesn't bother me, also because my vi mode allows to be move back and forth onto such a commandline with easy (escape ^; done).
 
Last edited:

olli@

Active Member
Developer

Reaction score: 210
Messages: 231

I am a hobbyist with respect to IT. But this is why I really like shells/ksh93. I have not tried shell/pdksh yet. Learning some key bindings and use them for many tools is marvelous.
But vi-mode is not unique to ksh. All common shells support vi-mode line editing. bash and zsh do, and even FreeBSD's /bin/sh supports it (even though it's otherwise not very well-suited for interactive use).
 

k.jacker

Aspiring Daemon

Reaction score: 330
Messages: 567

If anyone has ever tried to format multimedia/mplayer's "ICY Info" output strings from a script, has maybe grown some grey hair.
There are a lot of examples on the web using grep, cut, awk and sed, and that's what I was using, too.
Still it had some weaknesses.

Today I stumbled over some of my own examples from earlier this year, where I was learning to use back references.

What I use now, has become so short and simple, with no weaknesses anymore, I'd like to share it.
Code:
mplayer -msglevel all=0:demuxer=4 <url to radio stream> | grep --line-buffered -oe "\([\']\)[[:print:]]*\1"
Nice, tmux statusline ready output :D
'Dynoro feat. Gigi D'Agostino - In My Mind'
'Udo Lindenberg - Cello (feat. Clueso)'
'www.antennemv.de'
'Depeche Mode - People Are People'
'Milow - Lay Your Worry Down (feat. Matt Simons)'
'The Avener - Fade Out Lines'
'Jason Mraz - Have It All'
'R.E.M. - Losing My Religion'
'Adele - Someone Like You'


What the backreference does is, it greps everything between the first and the last single quote from the string:
ICY Info: StreamTitle='Dynoro feat. Gigi D'Agostino - In My Mind';

Redirect the output to a file and add the following to ~/.tmux conf
Code:
set -g status-left '#(tail -n1 /tmp/<filename>)'
 

Sensucht94

Well-Known Member

Reaction score: 361
Messages: 381

pdksh, and all its idependent derivatives (mksh, GNU ksh, OpenBSD ksh -oksh-, NetBSD ksh, AmigaOS SKsh) are originally born as free AT&T ksh88 clones, the way Linux is Unix clone (completely written from scratch, different at its core, compatible at its surface); the ksh one can find on commercial Unices, is AT&T ksh93, a new overall reshaped and improved version of ksh88, first released in '94, opensource under Eclipse Public License as of 2005, Illumos default system interpreter, developed until 2014 when the last version was released, and presumably now discontinued.
dtksh (CDE's shell, used also in the dtlogin Xsession script) and tksh are ksh93 derivatives providing shell-level mapping for Motif and Tk widget toolkits respectively. rksh is ksh93 acting in restricted mode

Although many patches providing cross-compatibility with new ksh93 additions were submitted to the various pksh versions throughtout the years, pdksh derivatives and ksh93 are not fully compatible, while pdksh derivatives usually are with one another

Generally speaking ksh93 is more complex (have a look at sources on github), one may say bloated;
Of all the pdksh derivatives, mksh is the most featured, providing bash/zsh -like extentions, while oksh is the most stripped down, clean, fast, but also barebones

None of those shells are POSIX-compliant by default (in spite of their significantly stronger adherence to POSIX compared to bash), but can operate in POSIX mode (set -o posix), which is what they do when invoked as /bin/sh
 

Vull

Active Member

Reaction score: 53
Messages: 141

I used the AIX version of ksh for years in my work environment which was dominated by AIX, SCO Openserver 5, and Red Hat 6.2, and it was my favorite shell. Here's an old script I wrote for changing the PS1 prompt, just to remind myself and other programmers which machine we had telnetted into, and to put the pathname in the prompt, which still wasn't all that common a thing in the 90s, and SCO still had just the "$ " or "# " prompts, and lacked the capability of putting the `pwd` present working directory pathname in the prompt. It's a bit crude and I'm almost ashamed to admit I wrote it, but it worked then and still works now. I no longer use AIX, SCO, or Red Hat, and have since modified it to work on FreeBSD and MacOS X 10.5.8, but it still has some of the old residue from those original three systems. Originally it was intended to use different sets of braces in the set {},[],<> to indicate the "flavor" of the OS, and it still has some of that in there too...
Code:
# logps1 - format PS1 shell prompts for bash, ksh, or sh shells
#
# --- Usage:  PS1=`logps1`;export PS1
#
# --- Show $PWD (print working directory) if shell is capable (bash or ksh).
# --- Show hostname or user name as specified locally by SHOWHOST and SHOWUSER.
# --- Indicate if user is superuser by "$" (user) or "#" (super-user) suffix.
#
SHOWHOST=1 #--- 0=don't show hostname in shell prompt, 1=show it.
SHOWUSER=1 #--- 0=don't show username in shell prompt, 1=show it.
#
#--- Only interpret bash, ksh, or sh shells. While checking the shell name, also

#--- set CANPWD=1 if shell prompt is capable of displaying the working directory

if [ "`echo $SHELL |grep -c /bash`" != "0" ];then
        THISSH=bash
        CANPWD=1
elif [ "`echo $SHELL |grep -c /ksh`" != "0" ];then
        THISSH=ksh
        CANPWD=1
elif [ "`echo $SHELL |grep -c /sh`" != "0" ];then
        THISSH=sh
        CANPWD=0
else #--- if neither bash, ksh, or sh is the shell, return $PS1 unchanged
        echo "$PS1"
        exit 0
fi
#--- Only interpret AIX, Red Hat, or SCO Openserver systems.  While checking,
#--- set ISSUPER=1 if shell is running as super-user.
ISSUPER=0
if [ -d /usr/lpp/bos ];then
        THISOS=aix #--- IBM AIX operating system for RISC system architecture
        PREFIX=\< ; SUFFIX=\>
        if [ "$LOGIN" = "root" ];then ISSUPER=1 ; fi
elif [ "`which freebsd-version`" != "" ];then
        THISOS=freebsd
        PREFIX=\[ ; SUFFIX=\]
        if [ "$HOME" = "/root" ];then ISSUPER=1 ; fi
# elif [ -f /boot/vmlinuz ];then
elif [ -d /boot ]&& [ "`ls /boot/vmlinu* 2>/dev/null`" != "" ];then
        THISOS=linux #--- presumably Red Hat Linux 6.2 or newer ---#
        PREFIX=\[ ; SUFFIX=\]
        if [ "$HOME" = "/root" ];then ISSUPER=1 ; fi
elif [ -d /var/opt/K/SCO ];then
        THISOS=unix #--- presumably SCO Unix OpenServer 5 or newer ---#
        PREFIX=\( ; SUFFIX=\)
        if [ "`env |grep '_=' |grep -c su`" = "1" ];then ISSUPER=1 ; fi
        if [ "$PS1" = "# " ]||[ "$LOGNAME" = "root" ];then ISSUPER=1 ; fi
elif [ -f /mach_kernel ];then
    THISOS=mac #--- presumably Apple's Mac OS X 10.5.8 or higher ---#
    PREFIX=\{ ; SUFFIX=\}
    if [ "$HOME" = "/var/root" ];then ISSUPER=1; fi
else #--- if neither aix, linux, or "unix" is the OS, return $PS1 unchanged
        echo "$PS1"
        exit 0
fi
#--- Get host name if specified, but strip off any domain name suffixes.
if [ "$SHOWHOST" != "0" ];then
        SHOWHOST=`hostname`
        SHOWHOST=`echo $SHOWHOST |awk 'BEGIN { FS = "." } { printf("%s",$1) }'`
fi
#--- format the shell prompt for the host, shell, and super-user level at hand
if [ "$SHOWUSER" != "0" ] || [ "$SHOWHOST" != "0" ];then
        PS1=$PREFIX; else PS1=
fi
if [ "$THISSH" = "bash" ];then
        if [ "$SHOWUSER" != "0" ];then PS1=$PS1"\u" ; fi
        if [ "$SHOWHOST" != "0" ];then PS1=$PS1"@\h" ; fi
else
        if [ "$SHOWUSER" != "0" ];then PS1=$PS1$LOGNAME; fi
        if [ "$SHOWHOST" != "0" ];then PS1=$PS1"@"$SHOWHOST; fi
fi
if [ "$CANPWD" != "0" ];then
        if [ "$SHOWUSER" != "0" ] || [ "$SHOWHOST" != "0" ];then
                PS1=$PS1" "
        fi
        PS1=$PS1"\${PWD}"
fi
if [ "$SHOWUSER" != "0" ] || [ "$SHOWHOST" != "0" ];then
        PS1=$PS1$SUFFIX
fi
if [ "$THISSH" = "bash" ];then
        PS1=$PS1"\n\\$ "
elif [ "$ISSUPER" != "0" ];then
        PS1=$PS1"# "
else
        PS1=$PS1"$ "
fi
echo "$PS1"
exit 0
(EDITED to add: Cleaned this up a little and added the capability to display the present working directory in the command prompt for Bourne shells (i.e., "sh" shells) under FreeBSD, since I'm not using SCO Openserver anymore, nor, I suspect, is anybody. One of the things I like about bash is the command prompt, and this will give me the same prompt while running sh shells under FreeBSD...)
Code:
# bsdps1 - format PS1 shell prompts for bash, ksh, or sh shells
# 2018-12-19 w jch
#
# --- Usage:  PS1=`bsdps1`;export PS1
#
# --- Show $PWD (print working directory) if shell is capable (bash or ksh).
# --- Show hostname or user name as specified locally by SHOWHOST and SHOWUSER.
# --- Indicate if user is superuser by "$" (user) or "#" (super-user) suffix.
#
SHOWHOST=1 #--- 0=don't show hostname in shell prompt, 1=show it.
SHOWUSER=1 #--- 0=don't show username in shell prompt, 1=show it.
PROMPTLINES=1 #--- 1=1 line prompt, 2=2 line prompt
              #--- NOTE: sh doesn't interpret "\n" and so won't display 2 lines
#
#--- Only interpret bash, ksh, or sh shells. While checking the shell name, also

#--- set CANPWD=1 if shell prompt is capable of displaying the working directory

if [ "`echo $SHELL |grep -c /bash`" != "0" ];then
        THISSH=bash
        CANPWD=1
elif [ "`echo $SHELL |grep -c /ksh`" != "0" ];then
        THISSH=ksh
        CANPWD=1
elif [ "`echo $SHELL |grep -c /sh`" != "0" ];then
        THISSH=sh
        CANPWD=1
else #--- if neither bash, ksh, or sh is the shell, return $PS1 unchanged
        echo "$PS1"
        exit 0
fi
#--- Sniff for AIX, Linux, SCO Openserver, Mac OSX, and FreeBSD systems. Also
#--- set ISSUPER=1 if shell is running as super-user.
ISSUPER=0
if [ -d /usr/lpp/bos ];then
        FLAVOR=aix #--- IBM AIX operating system for RISC system architecture
        PREFIX=\< ; SUFFIX=\>
        if [ "$LOGIN" = "root" ];then ISSUPER=1 ; fi
elif [ "`which freebsd-version`" != "" ];then
        FLAVOR=freebsd
        PREFIX=\( ; SUFFIX=\)
        if [ "$HOME" = "/root" ];then ISSUPER=1 ; fi
elif [ "`ls /boot/vmlin* |grep vmlinuz 2>/dev/null`" != "" ];then
        FLAVOR=linux #--- presumably Red Hat Linux 6.2 or newer ---#
        PREFIX=\[ ; SUFFIX=\]
        if [ "$HOME" = "/root" ];then ISSUPER=1 ; fi
elif [ -d /var/opt/K/SCO ];then
        FLAVOR=sco #--- presumably SCO Unix OpenServer 5 or better ---#
        PREFIX=\( ; SUFFIX=\)
        if [ "`env |grep '_=' |grep -c su`" = "1" ];then ISSUPER=1 ; fi
        if [ "$PS1" = "# " ]||[ "$LOGNAME" = "root" ];then ISSUPER=1 ; fi
elif [ -f /mach_kernel ];then
        FLAVOR=mac #--- presumably Apple Mac OS X or higher ---#
        PREFIX=\{ ; SUFFIX=\}
        if [ "$HOME" = "/var/root" ];then ISSUPER=1; fi
else #--- if none of the above systems, return $PS1 unchanged & exit normally
        echo "$PS1"
        exit 0
fi
#--- Get host name if specified, but strip off any domain name suffixes.
if [ "$SHOWHOST" != "0" ];then
        SHOWHOST=`hostname`
        SHOWHOST=`echo $SHOWHOST |awk 'BEGIN { FS = "." } { printf("%s",$1) }'`
fi
#--- format the shell prompt for the host, shell, and super-user level at hand
if [ "$SHOWUSER" != "0" ] || [ "$SHOWHOST" != "0" ];then
        PS1=$PREFIX; else PS1=
fi
if [ "$THISSH" = "bash" ];then
        if [ "$SHOWUSER" != "0" ];then PS1=$PS1"\u" ; fi
        if [ "$SHOWHOST" != "0" ];then PS1=$PS1"@\h" ; fi
else
        if [ "$SHOWUSER" != "0" ];then PS1=$PS1$LOGNAME; fi
        if [ "$SHOWHOST" != "0" ];then PS1=$PS1"@"$SHOWHOST; fi
fi
if [ "$CANPWD" != "0" ];then
        if [ "$SHOWUSER" != "0" ]||[ "$SHOWHOST" != "0" ];then
                PS1=$PS1" "
        fi
        if [ "$THISSH" = "sh" ];then
                PS1=$PS1"\w"
        else
                PS1=$PS1"\${PWD}"
        fi
fi
if [ "$SHOWUSER" != "0" ] || [ "$SHOWHOST" != "0" ];then
        PS1=$PS1$SUFFIX
fi
if [ $PROMPTLINES -eq 2 ];then PS1=$PS1"\n"; fi

if [ "$ISSUPER" != "0" ];then
        PS1=$PS1"# "
else
        PS1=$PS1"$ "
fi
echo "$PS1"
exit 0
 
Last edited:

Vull

Active Member

Reaction score: 53
Messages: 141

Self-extracting installer script:

The "exex" script has 2 functions. If it's executed with command line arguments, it attempts to perform the Create() function, and if it has no command line arguments, it attempts to perform the Extract-and-Execute function. This has been tested on FreeBSD 11.2 and 12.0, and on Debian 9.5 and 9.6.

1. The "Create()" function creates a single executable file by concatenating 3 separate files, one after the other:
1. A. The first file included in the self-extracting executable is the exex script itself.
1. B. The second file included in the self-extracting executable is a separate script which will run right after the archive is extracted. In the example provided here, it will unzip the archive and start the installation of the software in the archive.
1. C. The third file included in the self-extracting executable is the archive itself.

2. The "Extract()" function is the function which extracts the archive from the concatenated file. After the extraction has been done, the 2nd file will be executed automatically. The automatic execution depends on the fact that the exex script has no 'exit' statement, and therefore, since the 2nd file comes right after the first, control will pass immediately from the last executed statement in the first file to the first executable statement in the 2nd file. For further documentation please refer to the comments in the two scripts. The first script is the exex file itself, and the 2nd script is an example of what can be done automatically after the archive has been extracted.

exex
Code:
#!/bin/sh
# 2018-12-19 w jch - modified for better posix compliance
#-------------------------------------------------------------------------------
# exex - create the SXE (mode=c), or (ex)tract & (ex)ecute the SXE (mode=x)
# ----   ------     ---  ------       --          --           ---  ------
# SXE = (S)elf-e(X)tracting-(E)xecutable script file

Create() { #--- Create the whole self-extracting archive and executable script.

  #--- get the file size of this file, which will be the first file in the sxe,

  size1=`ls -l $0 |awk 'BEGIN{FS=" "}{printf("%s",$5)}'`

  #-- and the size of the user-provided script file, which will be the 2nd file,

  size2=`ls -l $script |awk 'BEGIN{FS=" "}{printf("%s",$5)}'`
  
  #--- and the size of the user-provided archive, which will be the 3rd file

  # size3=`ls -l $archive |awk 'BEGIN{FS=" "}{printf("%s",$5)}'`

  #--- NOTE: we don't actually need to know size3, hah, so I commented it out.

  #--- Build a candidate line 2, which will be interpreted as a comment when
  #--- the combined script files run. The two scripts will execute one after the
  #--- other, like a single script. The size info line 2 comes right after the
  #--- shebang line, i.e., the line that says: "#!/bin/sh" ... The magical
  #--- importance of the inserted 2nd line is that it provides info to the
  #--- Extract() function, as to exactly where the user-provided archive file
  #--- begins, so it can be extracted from the sxe, and made into a usable
  #--- copy of the original archive. Thus, it must also contain the name of that
  #--- original user-provided archive. This Create() function will also insert
  #--- an "exit 0" at the end of the user provided script file, so the shell
  #--- won't try to execute the archive, which will be tucked in this file when
  #--- the exex script and the user provided script are executed together, as
  #--- one. The shell will interpret the two scripts together in one pass, like
  #--- they were a single script, and that's what makes it "self-executing."

  exitcommand="exit 0"    #--- The actual length of this line will be 7,
  # exitcommandlength=7   #--- 6 for the characters, plus 1 for the "\n" char.

  #--- Now begins a series of approximations of the exact offset of the archive.

  offset=$(($size1+$size2+7+4+${#archive})); # We know where the 7
  #--- in this offset sum came from, and the 4 in the same calculation is for
  #--- the length of the 3 # chars and the \n in the line 2 info comment. Then
  #--- we add the length of the NAME of the archive file, NOT the length, or
  #--- the size, of the actual archive file, because the name of the file will
  #--- be the 2nd item of info in the info comment line.
  
  #--- Now the 2nd, closer approximation: The problem is the decimal string len.
  offset2=$(($offset+${#offset})) #--- Add string length of offset.
  offslen=${#offset} #--- The approx. length of the decimal string.
  offslen2=${#offset2} #--- offslen is 1 estimate, offslen2, closer

  #- Make offslen2 the EXACT offset, after 1st seeing if the length "rolls over"
  #- (like speedometer mileage), for example, 999 is 3 digits, 1000 is 4 digits.

  if [ $offslen2 -gt $offslen ]; then $offset2=$(($offset2+1)); fi
  line2='#'$offset2'#'$archive"#" #--- Now, finally, offset2 = the exact offset

  # Oh I know, I could've just used a few # chars for padding, but it was fun:)!

  #--- Create a temporary filename for the tmp directory,

  tmpf=$HOME/grip/tmp/exexarchive.`wasat.who` #( wasat.who = pts.0, tty1, etc.,)
                                              #( something unique to this user.)

  #--- add the first line of this file (the shebang line) to the temporary file,

  line1=`awk 'NR==1{print $0}' $0` #(Select NR (Number of Record)=1,which means)
                                   #(the 1st line. (R)ecord=row, (F)ield=column)
  echo $line1 > $tmpf

  #--- followed by the 2nd info or comment line, which we need to insert, so the
  #--- Extract() function can use that info, and will know where to find it,

  echo $line2 >> $tmpf

  #--- Now, add lines 2 through the end of file, of the exex file, after line 2,

  tail -n +2 $0 >> $tmpf

  #--- and then add all the lines of the user supplied script file after that,

  cat $script >> $tmpf

  #--- and add the exit 0 command after the user supplied script, just in case,
  #--- because we wouldn't want the shell interpreter interpreting the archive.

  echo $exitcommand >> $tmpf

  #--- and add the archive file,

  cat $archive >> $tmpf

  #--- and rename it, at the same time moving to the path specified in the name,

  mv $tmpf $sxe
  chmod +x $sxe #--- and then, finally, make the whole file executable.

  echo 'Finished creating "'$sxe'"'
}

Extract() { #--- Extract the user-provided archive file, and then the 2nd part
            #--- of this file will execute, right after this function executes.

  #--- The shell interpreter's timing considerations will make the 2nd script
  #--- wait for the archive to be extracted, just like we have to wait for a
  #--- command to finish before the shell shows us the next command prompt.

  line2=`head -n 2 $0 |awk 'NR==2{print $0}'`
  offset=`echo $line2 |awk 'BEGIN{FS="#"}{printf("%s",$2)}'`
  archive=`echo $line2 |awk 'BEGIN{FS="#"}{printf("%s",$3)}'`
  if [ ! -f $archive ]; then
    tail -c +$(($offset+1)) $0 > $archive
  fi
}

Syntax() { #--- Complain about syntax errors and/or any type of errors, & exit.

  if [ "$mes" != "" ]; then
    echo
    echo "Error:  *** "$mes" ***"
  fi
  echo
  echo "Syntax:"
  echo "  exex scriptFile archiveFile nameForNewSelfExtractingExecutable"
  echo
  exit 1
}

#--- ma(in lo)gic

#--- Determine if we're running in create mode, or in extract and execute mode.

mode= #--- if filename is exex, run in create mode, otherwise, use ex & ex mode

mes= #--- error message for the Syntax() function

name=`echo $0 |awk 'BEGIN{FS="/"}{printf("%s",$NF)}'` #--- this filename

if [ "$name" = "exex" ]; then mode=c; else mode=x; fi

case "$mode" in

  ("c") #--- Create the archive

    #--- First check the command line arguments.
    exex=$0
    script=$1
    archive=$2
    sxe=$3 #--- S.X.E. is bad language for (S)elf e(X)ecuting (E)xecutable.

    if [ "$sxe" = "" ]; then Syntax; #--- If last one is empty all 3 are empty.
    elif [ ! -f $script ]; then
      mes='Script file: "'$script'" not found.'; Syntax
    elif [ ! -f $archive ]; then
      mes='Archive file: "'$archive'" not found.'; Syntax
    elif [ -f $sxe ]; then
      mes='Target file: "'$sxe'" already exists.'; Syntax 
    fi

    Create
     ;;

  ("x") #--- Extract the user-provided archive file, which is file section 3 in
        #--- this weird file, and then let the shell interpreter start
        #--- interpretting the user-provided script, which is file section 2.
        #--- We are now close to the end of file section 1. Thanks for visiting.

    Extract
     ;;
  (*) ;;
esac

#--- PROGRAMMER(S): THIS IS IMPORTANT! Do NOT add an exit command, and PLEASE,

# exit 0 #--- PLEASE, DON"T uncomment THIS line, or the user's script file
#        won't be executed! Which would thwart the whole purpose of this file.

#--- BECAUSE: we want the two scripts to run together, like a single script.
#-------------------------------------------------------------------------------
execute-install
Code:
#!/bin/sh
# execute-install - bootstrap script for self-extracting installer which s.b.
#   created by the non-root user running exex w/ this 2 step command sequence:
#
# cd $HOME
# exex grip/install/freebsd11.2.d/execute-install xfer.tar install-wasat
#
# Note: this is not an executable script, but rather, install-wasat will be.

# 2018-8-30 h 081 jch |# 2018-8-31 f 079 jch # 2018-9-16 n 088 jch
# 2018-10-15 m 094 jch |# 2018-10-20 m 094 jch |# 2018-11-3 s jch
# 2018-11-24 s jch - from grip/install/debian9.5.d -> grip/install/freebsd11.2.d

dv='11.2'
installdir='grip/install/freebsd'$dv'.d'
subnet=dashnet

oldpath=`pwd`
cd $HOME
#--- Check if system is partially installed (and still needs to have setup done)

echo "Checking if system is already (partially) installed ... "

h=/usr/local/www/apache24/data
if [ -f $h/wasat/setup-wasat.php ]; then
  DISPLAY=:0; export DISPLAY

  firefox "https://`hostname`.$subnet/wasat/setup-wasat.php" &

  cd $oldpath
  exit 0
fi
#--- Check if system appears to be completely or partly/unsuccessfully installed

if [ -d $h/wasat ]||[ -d $HOME/grip ]; then
  echo
  if [ -d $h/wasat ]; then
    echo 'Your system appears to be already installed in "'$h'/wasat/".'
  else
    echo "Your system appears to be partially installed."
    echo "There is a 'grip' directory in your home directory."
  fi
  cd $oldpath
  exit 0
fi
#--- Start unpacking the xfer.tar archive

echo -n "... Preparing to install the pre-packaged software ... "

tar -xf xfer.tar
tar -xzf xfer/grip.tar.gz
if [ ! -d $HOME/Desktop ];then mkdir $HOME/Desktop; chmod 700 $HOME/Desktop; fi
if [ ! -d $HOME/Desktop/0 ]; then mkdir $HOME/Desktop/0; fi
if [ "`ls xfer/wasat* 2>/dev/null`" != "" ]; then
  cp -p xfer/wasat* Desktop/0/
fi
echo
#--- Execute the install script

echo "... Starting the installation process ..."

$installdir/install |tee $installdir/install.log

inp=
if [ -f $h/wasat/setup-wasat.php ]; then
  echo
  while [ "$inp" != "y" ]&&[ "$inp" != "n" ];do
    echo -n "Would you like to continue with the setup now? [y/n] "; read inp;
    if [ "$inp" != "" ]; then inp=`echo $inp | tr [:upper:] [:lower:]`; fi
    case "$inp" in ("yes") inp=y;; ("no") inp=n;; ("y");; ("n");;
      (*) echo "Please answer yes or no (or y or n)."; inp="";;
    esac
  done
  if [ "$inp" = "y" ]; then
    echo "Launching the setup program now..."
    DISPLAY=:0; export DISPLAY
    firefox "https://`hostname`.$subnet/wasat/setup-wasat.php" &

    #--- message to keep terminal open in case installer was desktop-launched
    echo
    echo "Please leave this Terminal open until your Firefox session is"
    echo "closed, or your Firefox session may also be suddenly closed."
    echo
  fi
fi
cd $oldpath
exit 0
 

Vull

Active Member

Reaction score: 53
Messages: 141

Shell script to display FreeBSD package dependencies recursively:

Code:
#!/bin/sh
# pkg-dependencies - recursively display package dependencies / FreeBSD 12.0R
# 2019-1-18 f jch

# Uses a /tmp dir. work file to avoid listing the same packages more than once.
# May be interrupted with CTRL-C

trap Cleanup 1 2 3 6

Cleanup() {
  #-- delete the work file(s)
  rm -rf /tmp/pkg-dependencies-work*
  exit 1
}
Recurse() {
  pkgroot=$1
  if [ "$2" = "" ];then
    lvl=0 #-- recursion level
    pid=$$ #-- pid of top level parent process
  else
    lvl=$2
    pid=$3
  fi
  workf=/tmp/pkg-dependencies-work.$pid
  if [ $lvl -eq 0 ]; then
    #-- create work file
    rm -rf $workf
    touch $workf
  elif [ ! -f $workf ]; then
    exit 1 #-- program interrupt must have occurred and deleted the work file
  fi
  #-- generate list of dependent packages using pkg info command
  list=$(pkg info -d $pkgroot)
  n=0
  for pkg in $list; do
    n=$(($n+1)) #-- sequence number in list from pkg info command
    if [ $n -eq 1 ]; then #-- this is package name arg followed by a ":" char
      #-- display the top level package name followed by ":"
      if [ $lvl -eq 0 ]; then echo 'Package dependencies for '$pkg; fi
    else
      #-- for sub-packages, display package name after a "tab line" of "." chars
      tab=
      x=$(($lvl+1)) #-- display one "." for level 0, 2 for level 1, etc.
      while [ $x -gt 0 ]; do
        tab=$tab"."
        x=$(($x-1))
      done
      #-- check work file to learn if package name has already been displayed
      grepout=$(grep $pkg $workf)
      echo $pkg >>$workf #-- add package name to work file
      if [ "$grepout" = "" ]; then #-- package has not been displayed so do it
        echo $tab $pkg #-- display tab line and package name
        $0 $pkg $(($lvl+1)) $pid #-- invoke recursion to show sub-dependencies
      fi
    fi
  done
  if [ $lvl -eq 0 ]; then
    rm -f $workf
  fi
}

Syntax() {
  echo
  if [ "$mes" != "" ]; then
    echo "Error:  *** "$mes" ***"
    echo
  fi
  echo "Syntax: pkg-dependencies packageName"
  echo
  exit 1
}

mes=
if [ "$1" = "" ];then Syntax; fi
Recurse $*
exit 0
 

olli@

Active Member
Developer

Reaction score: 210
Messages: 231

While we're at it ... This is my version of a script that displays package dependencies recursively. It doesn't use any temporary files.
Code:
#!/bin/sh -
#
#   This script calls "pkg info" repeatedly in order to generate
#   recursive lists of dependecies (-d) or required-by (-r).
#

set -Cefu
ME="${0##*/}"

DEBUG=false
#DEBUG=true

if $DEBUG; then
        echo "#### $ME $*" >&2
fi

Usage()
{
        echo "Usage:  $ME {-d | -r} <package> [...]" >&2
        exit 1
}

if [ $# -lt 2 ] || [ "x$1" != x-d -a "x$1" != x-r ]; then
        Usage
fi

FLAG="$1"
shift

ARGS="$*"
LIST="%"

while :; do
        if $DEBUG; then
                echo "==== pkg info -q $FLAG $ARGS" >&2
        fi
        PKGS="$(pkg info -q $FLAG $ARGS)" || {
                echo "WARNING: Exit code from pkg: $?" >&2
        }
        if $DEBUG; then
                if [ -z "$PKGS" ]; then
                        echo "---- No output." >&2
                else
                        echo "---- Output:" >&2
                        echo "----" $PKGS >&2
                fi
        fi
        if [ -z "$PKGS" ]; then
                break
        fi
        NEW_ARGS=""
        for P in $PKGS; do
                case "$LIST" in
                        *"%${P}%"*)
                                ;;
                        *)
                                LIST="${LIST}${P}%"
                                NEW_ARGS="$NEW_ARGS $P"
                                ;;
                esac
        done
        if [ -z "$NEW_ARGS" ]; then
                break
        fi
        ARGS="$NEW_ARGS"
done

echo -n "${LIST#%}" | tr '%' '\n'
The script is called with either -d or -r, followed by the name of the package. The meaning of the two options is the same as for pkg info, see the pkg-info(8) manual page.
 
Top