LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Slackware (https://www.linuxquestions.org/questions/slackware-14/)
-   -   Useful custom commands for Slackware (https://www.linuxquestions.org/questions/slackware-14/useful-custom-commands-for-slackware-174647/)

thegeekster 04-26-2004 06:08 AM

Useful custom commands for Slackware
 
Here are three commands I use which I find quite useful. They all deal with finding info on the Slackware packages currently installed on the computer and are a great addition to the other package commands in Slackware (such as installpkg, removepkg, upgradepkg, etc.). These are my own homegrown commands, not copied from anywhere, which I give freely to the public domain without restriction. They are script files which can be placed in /usr/local/bin and used like any other command.

Each has a short help message to help with usage, although I will provide a quick rundown on their usage. They require the utils 'less' (less pkg) and 'egrep' (grep pkg), which may or may not be installed by default.

PATTERN MATCHING <- This section has been edited. ->
All the scripts now emulate the wildcard pattern matching ( * and ? ) used for filename matches. These scripts do not use true globbing, as it is sometimes called, but merely substitutes the wildcards * and ? with a regular expression equivalent, which is only part of the picture (see 'man glob' for details for the rest of the story on wildcard pattern matching). This is sufficient for what is needed for these scripts. Using more complicated searching, such as with the square brackets ( [ ] ), curly braces ( { } ), and others used in globbing, will not work as expected as the rules are different than how they are applied in regular expressions (used by the 'egrep' command). I suppose I could do more substitution to make it closer to globbing, but I really don't see the need to do so at this time. NOTE: If your familiar with the extended regexp syntax, you could probably do more complicated searches with these scripts, if you remember to take into account the substition of * for .*, ? for .?, and . for \. ............


NOTE: Any changes or updates in code will be reflected here and explained in a following post below...........In other words, the code for these three scripts will always have the most recent changes in this post with an explanation in another post below.

lspkg
This command simply lists the packages currently installed on your machine.

UPDATE: See post #53 below for more info.
Code:

#!/bin/sh
#*******************************************************************************
# Name: lspkg
#
# A Slackware tool which simply lists the currently installed packages.
#
# Originally written by CTWaley (a.k.a., thegeekster) and originally posted in
# the Slackware forum at LinuxQuestions.org,
# <http://www.linuxquestions.org/questions/showthread.php?postid=899459#post899459>
#
# This program is given to the Public Domain and is free software. You can
# redistribute it and/or modify it without restriction of any kind.
#
# It 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.
#*******************************************************************************

case $1 in
  -h | --help )  # If -h (--help) is given as an argument, show the usage.
    cat << __EOF__

Usage: lspkg [<package_name> ... ]

Lists the Slackware packages currently installed. If no argument is
given, it will output all packages currently installed. If an argument
is given on the command line, it will look for the package name matching
the pattern(s) supplied. More than one package name or pattern may be
given on the command line.

Use the wildcards * and ? when looking for a package name containing the
characters supplied on the command line. For example, to find a package
containing the word "lib", but does not necessarily begin with "lib",
use one of the patterns "*lib", "?lib", "??lib" or even "??lib*". To see
if you have both "bzip" and "bzip2" installed on your system, you can
use the search term "bzip?".  You may also enclose the search pattern in
single quotes (') or double quotes (") to avoid the shell interpeter from
interfering with the search term when using the wildcard characters.

__EOF__
    ;;
  * )
    [ -z $1 ] && 'ls' /var/log/packages/ | less \
    || {
      while [ ! -z $1 ]
      do
        pkg=`echo $1 | sed 's/\./\\./g; s/\*/.*/; s/\?/.?/g'`
        'ls' /var/log/packages/ | egrep -i "^$pkg\>"
        shift
      done | more
    }
esac


pkginfo
This command lists the package's name, size of the package, the package description, and a list of the files installed by the package.

UPDATE: See post #53 below for more info.
Code:

#!/bin/sh
#*******************************************************************************
# Name: pkginfo
#
# A Slackware tool to find the inforamtion about any installed package.
#
# Originally written by CTWaley (a.k.a., thegeekster) and originally posted in
# the Slackware forum at LinuxQuestions.org,
# <http://www.linuxquestions.org/questions/showthread.php?postid=899459#post899459>
#
# This program is given to the Public Domain and is free software. You can
# redistribute it and/or modify it without restriction of any kind.
#
# It 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.
#*******************************************************************************

count_args() {
  args=$#
}

present_list() {
  cat << __EOF1__ | more

-------------------------------------------------------------------------------
 More than one package was found matching the name, "$ARG".
 Choose a package from the following list (Hint: Use the mouse to copy-n-paste
 the desired package name)...
-------------------------------------------------------------------------------

`echo "$PKGS" | egrep -i "\<$1\>" | while read i ; do basename $i ; done`

-------------------------------------------------------------------------------
__EOF1__

  echo -n " Enter package name here: " ; read pkg
  count_args `echo "$PKGS" | egrep -i "\<$pkg\>"`
  { [ $args -gt 1 ] && present_list $pkg
  } || {
    [ $args -lt 1 ] \
      && echo "No package was found matching the name, \"${pkg}\"." \
      && exit 1
  }
}

view_info() {
  cat << __EOF2__ | less
`cat \`echo "$PKGS" | egrep -i "\<$1\>"\``

`echo "INSTALLATION SCRIPT:"`
`cat \`echo "$SCRIPTS" | egrep -i "\<$1\>"\``
__EOF2__
}

case $1 in
  # If no argument or -h (--help) is given as an argument, show the help message.
  "" | "-h" | "--help" )
    cat << "__EOF3__"

Usage: pkginfo <package_name>

Lists the contents of the requested package. You can give any part of
the package name (such as bash, bash-2.05b, 2.05b, bash-2.05b-i486,
etc.). The search is case insensitive (upper- or lowercase is okay).
You may use the wildcards "*" or "?" for pattern matching. If more
than one match is found, you will be presented with a list of package
names to choose from (like when searching for the package xfree86).

TIP: If you know the first few letters of the package you are looking
    for, add the asterisk (*) at the end of the search term, such as
    "lib*". Or to find packages which end with the search term entered
    on the command line, add the "*" wildcard in front of the term
    (ie., "*lib"). You will then be presented with a list of package
    names to choose from. You may also enclose the search pattern in
    single quotes (' ') or double quotes (" ") to avoid the shell
    interpeter from interfering with the search term while using the
    wildcard characters.

__EOF3__
    ;;
  * )
    count=0
    ARG="$1"
    F="`echo \"$1\" | sed 's/\./\\./g; s/\*/.*/; s/\?/.?/g'`"
    PKGS=`find /var/log/packages/* -type f -prune`
    SCRIPTS=`find /var/log/scripts/* -type f -prune`
    count_args `echo "$PKGS" | egrep -i "\<$F\>"`
    case $args in
      0 )
        echo "No package was found matching the name, \"$ARG\"."        ;;
      1 )
        [ -z `echo "$SCRIPTS" | egrep -i "\<$F"` ] \
          && cat "`echo \"$PKGS\" | egrep -i \"\<$F\"`" | less \
          || view_info "$F"
        ;;
      * )
        present_list $F
        [ -z `echo "$SCRIPTS" | egrep -i "\<$pkg\>"` ] \
          && cat "`echo \"$PKGS\" | egrep -i \"\<$pkg\>\"`" | less \
          || view_info "$pkg"
        ;;
    esac
esac


whichpkg
Ever wonder which package a file came from? That's the purpose of this command, to find the package a file comes from.

UPDATE: See post #53 below for more info.
Code:

#!/bin/sh
#*******************************************************************************
# Name: whichpkg
#
# A Slackware tool to find which package a file comes from.
#
# Originally written by CTWaley (a.k.a., thegeekster) and originally posted in
# the Slackware forum at LinuxQuestions.org,
# <http://www.linuxquestions.org/questions/showthread.php?postid=899459#post899459>
#
# This program is given to the Public Domain and is free software. You can
# redistribute it and/or modify it without restriction of any kind.
#
# It 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.
#*******************************************************************************

search_pkgs() {
  name1="/${1}\>"

  find /var/log/packages/* -type f -prune | while read file
  do
    # This makes certain assumptions about where to look, such as
    # ignoring certain directories and files which are easy to figure
    # out where the files came from:
    cat $file | egrep -A5000 'FILE\ LIST:' | egrep -i "${name1}\$"\
      | egrep -v '(FILE\ LIST:|^\./$|\<install/|\<install-sh|\<install\.sh)' \
      | egrep -v '(usr/src/linux|doc/|share/$1)' \
      | while read line
    do
      [ ! -d $file ] && echo "`basename $file`:/$line"
    done
  done

  # Due to a problem of a broken pipe when trying to find any symlinks
  # associated with the file "ln", I had to find a workaround.
  name2="\<${1}\>"
  [ "$1" = "ln" ] && name2="\<ln\>\ [^-rf]"
  [ "$1" = "rm" ] && name2="\<rm\>\ [^-rf]"

  find /var/log/scripts/* -type f -prune | while read file
  do
    cat $file | egrep -i "$name2" \
      | egrep -v '(^#|:| \<rm\ -r\>|\<if\ |\<else\ |>>|\$|\<for\ .*\ in\>|doinst\.sh)' \
      | while read line
    do
      [ ! -z "`echo $line | egrep '\<ln\ -sf' |egrep '\(\ cd'`" ] \
        && echo "`basename $file`:/`echo $line \
        | awk '{ print $3\"/\"$8\"  --linked-to->  \"$7 }'`"
      [ ! -z "`echo $line | egrep '\<mv\ '`" ] \
        && echo "`basename $file`:/`echo $line | sed 's/^.*\(\<mv\ \)/\1/' \
        | awk '{ print $2\"  --renamed-to->  \"$3 }'`"
    done
  done
}

case $1 in
  "" | -h | --help )  # If no argument is given, or -h (--help) is given,
                      # as an argument then show the usage.
    cat << "__EOF__"  | less

Usage: whichpkg FILE1 [ FILE2 ... ]

Finds which Slackware package contains the file supplied on the command
line. A filename must be supplied and more than one filenam may be used
on the command line. For pattern matching, you may use the wildcards *
and ?. For example, to find the files "bzip" and "bzip2", you may use
the pattern "bzip?" to look for both files. The search is case
insensitive (upper- or lowercase is okay). You may also enclose the
search pattern in single quotes (') or double quotes (") to avoid the
shell interpeter from interfering with the search term when using the
wildcard characters.

The output was made to be as easy as possible to read and the output
for each search term is easily identifiable. Each matching line will
look something link this:

    <package_name>:<matched_path>

For symlink matches, the output will look something like this:

    <package_name>:<matched_symlink>  -- linked to->  <real_file>

If a file was renamed when installed, the output will look something
like this:

    <package_name>:<old_filename>  -- renamed to->  <new_filename>

To give you an idea, here's a sample output for the search for the
multiple terms "sh" and "bash":

$ whichpkg sh bash
------------------------------------------------------------------------
Searching for "sh"...

aaa_base-9.1.0-noarch-1:/bin/sh  --linked to->  bash

------------------------------------------------------------------------
------------------------------------------------------------------------
Searching for "bash"...

aaa_base-9.1.0-noarch-1:/bin/sh  --linked to->  bash
bash-2.05b-i486-3:/bin/bash  --renamed to->  bin/bash.old
bash-2.05b-i486-3:/bin/bash2.new  --renamed to->  bin/bash
bash-2.05b-i486-3:/usr/bin/bash  --linked to->  /bin/bash

------------------------------------------------------------------------


NOTE: The searches will take a couple of moments for each term being
      searched and some searches may take longer than others, depending
      on the keyword used. Usually it depends on how many occurrences of
      the keyword is found, which then must be analyzed and filtered.

__EOF__
    ;;
  * )
    while [ ! -z "$1" ]
    do
      i="`basename \`echo \"$1\" | sed 's/\./\\./g; s/\*/.*/; s/\?/.?/g'\``"
      echo "------------------------------------------------------------------------"
      echo -e "Searching for \"${1}\"...\n"
      search_pkgs "$i" | sort
      echo -e "\n------------------------------------------------------------------------"
      shift
      done        ;;
esac


I hope you find these as useful as I have. While you can get the same information using a graphical package manager, they are much quicker to use from the command line.

Enjoy :)
---thegeekster

Ninja Cow 04-26-2004 07:24 AM

You rock, sir.

I especially like lspkg. Nice and handy. Thank you very, very much.

thegeekster 04-26-2004 02:48 PM

Thanx :)

But I did notice one little item in the code for whichpkg...............I forgot to add the -i switch in the grep command. It's this switch that makes the search case insensitive...............................LOL...which means I've been using it all this time as a case sensitive search...... :eek:

I've already made the changes in the code above..............................but for those who may have copied it already, at the bottom of the code for 'whichpkg' change the two grep lines to read "grep -i ..." (simply insert -i after the word grep)........

thegeekster 05-17-2004 07:18 AM

*** lspkg UPDATE ***
 
NOTE: This update is superseded by the changes posted here..... :)

the who 05-17-2004 09:02 AM

Thanks, been using these scripts since you first posted them. :)

slakmagik 05-17-2004 01:02 PM

I don't think I've ever posted one of my scripts before. I figure mine suck. As far as this, I've just been using this thing I wrote called 'sp' (Slack packages).
Code:

script=`basename $0`
pkgdir=/var/log/packages/*
all=/home/j/var/manifest

usage () { printf "$script: Usage: $script OPTION SEARCHTERM
-a Search the entire manifest
-f Search for a filename within installed packages only
-s Search for a string within installed packages only
-v View the description file of a filename search (like -f)
"
}

if [ $# -ne 2 ]; then
        usage
        exit
fi

case $1 in
        -a) less +/$2 $all
                ;;
        -f) grep -i \/$2$ $pkgdir | less
                ;;
        -s) grep -iR $2 $pkgdir | less
                ;;
        -v) less `grep -i \/$2$ $pkgdir | cut -d: -f 1`
                ;;
        *) usage
                ;;
esac

Mine's real simple-like and lame, I guess. But it does interrogate 'manifest' in a half-assed way which will help you know if Slack provides something at all, whether you installed it or not, so I post it up as something somebody might want to improve and use. I'm sure you could create an actually useful script for MANIFEST.bz2 (I uncompressed it and and copied it to a sysjunk directory) to add to the suite.

But how every Slack user doesn't come up with *something*, I dunno. It's too common an activity and pkgtool is just too slow. ;) Good stuff, thegeekster.

Oh, and my less is 'export LESS="-eFMRXj12"' - using the default less the way I do might be kind of annoying.

Oh, and
alias cdp='cd /var/log/packages'
is essential for manual inspection. Due to filenames, typing 'cd /v<tab>log/p<tab>' sucks.

thegeekster 05-17-2004 07:03 PM

Hey, digiot, don't sell yourself short..................this is what open source is about, posting what you have for the benefit of others and if someone knows of a better or more efficient way of doing it, or spots a bug, then it gets fixed...........in other words, community involvement...............I'm sure mine can be improved upon, too.........

This is also why I post these scripts, making it useful for others and hoping others will come forward and help contribute their bit to the community.............and this allows users to have more choices, instead of limiting choices........... ;)

I see your code is basically what I have, but all in one program, with one added ability..................I thought of making it all one script, but then I decided to follow the Unix programming philosophy of making a program do just one thing, and do it well.... :)

I must say, I never thought of using the manifest file for searching if a file is part of the distribution as a whole, whether the pkg is installed or not...................gives me an idea of updating the 'whichpkg' script to first search locally for installed programs, and if not found, then search the manifest to see if it's even part of the Slackware distribution..................otherwise, it must be a third-party app and not officially part of Slackware.......... :)

Also, you might be interested in knowing that you can 'cat' a zipped file (reading the file to the screen), whether compressed with gzip or bzip2, since they only compress a single file. The regular zip utility doesn't do this AFAIK, probably due to the fact it is not limited to compressing only a single file...................In other words, instead of unzipping the manifest file, just 'cat' the file in it's compressed form...............this way, you can save some disk space and still be able to read the file and pipe it through grep to filter the output

The commands for these formats is zcat filename.gz for gzipped files and bzcat filename.bz2 for bzip2 files.......this will output the contents of the compressed file to the screen........so for your 'all' variable and '-a' switch you can do something like this:
Code:

all=/home/j/var/MANIFEST.bz2

...

 <EDIT>  -a) bzcat $all | grep -i $2  ;; </EDIT>

You get the idea.......... :)

And anyone else.................feel free to step in and post someting you may have come up with..............if you know of a useful timesaver, then post it.... :)

slakmagik 05-17-2004 11:06 PM

Quote:

Originally posted by thegeekster
Hey, digiot, don't sell yourself short..................this is what open source is about, posting what you have for the benefit of others and if someone knows of a better or more efficient way of doing it, or spots a bug, then it gets fixed...........in other words, community involvement...............I'm sure mine can be improved upon, too.........

Thanks - yeah, I agree - I wish more people would toss shell scripts back and forth but I guess I'm part of the problem there. ;)

Also, you might be interested in knowing that you can 'cat' a zipped file...
Yeah, but I'd still have to less it to position the file on the search argument and less gets lost when it's reading from stdin - reading a file off disk I can get

/home/j/var/manifest lines 21792-21811/217164 8%

instead of

lines 1-22

(or whatever) in the status line which I figure might be useful for something. And with disk sizes these days I don't compress much.

I second that, though - I look forward to more folks' posts. :)

(OT - anyone else feel claustrophobic. ;) )

thegeekster 05-18-2004 02:05 AM

Quote:

Originally posted by digiot
Yeah, but I'd still have to less it to position the file on the search argument and less gets lost when it's reading from stdin - reading a file off disk I can get...
I just discovered that less will read a compressed bz2 file just as easily as if it was not compressed:
Code:

all=/home/j/var/MANIFEST.bz2

...

    -a) less +/$2 $all

Try it and see......

And I'm not that familiar with the 'less' command, other than piping something to less.................so I learned something new and gives me something to play around with...... :)

slakmagik 05-18-2004 02:41 AM

:o

Yeah. lesspipe.sh. I forgot that. :( Well, if you're not familiar with less, check out the man page - it's a great tool that can be a lot more effective than I think a lot of people realize. I obviously need to go read it again myself ;)

(Still like 'em uncompressed, though.)

thegeekster 06-06-2004 12:31 AM

*** chngcd ***
 
Here's a handy little script for changing CDs easily..................This is especially useful for you gamers whom oftentimes have to change a CD during gameplay........

To use, it's quite simple - open a console terminal and enter chngcd..........The CDROM tray will pop out automatically..........Then place a CD in the tray -OR- replace the current CD to continue -OR- remove the CD to quit, and then press Enter................You don't even have to close the CD tray, it will do it automaticallly................Simple and effective... ;)

To make it easy to create the script, just copy-n-paste _all_ of the following code at once into a console terminal, and the script will be created automatically, not to mention being executable as well.......... :)

If you prefer to do it the harder way, such as using a text editor, then copy-n-paste everything _except_ the first and last lines into the text editor...........Do not copy the lines containing __EOF__

NOTE: If you need to change the path to the CDROM mount point for any reason, after creating the script just open it up and change the CDROM variable to the desired path..........

Code:

cat << "__EOF__" > /usr/local/bin/chngcd && chmod 755 /usr/local/bin/chngcd
#!/bin/sh
#*******************************************************************************
# Name: chngcd

# Mount point for CDROM device
CDROM=/mnt/cdrom

umount -l $CDROM 2> /dev/null
eject $CDROM

echo -en "\n After replacing or removing the CD, simply press [Enter]..." \
  && read ans && echo
mount $CDROM 2> /dev/null
__EOF__

Oh yeah, this is a script I made up myself and didn't copy it from anyone. This script is also donated to the public domain, and free to use without restriction........ :)

gnashley 06-06-2004 02:47 AM

Since a few bash scripters are gathered here, I'll ask here.
How can parse root=/dev/????? out of /proc/cmdline?

thegeekster 06-06-2004 03:11 AM

Quote:

Originally posted by gnashley
...How can parse root=/dev/????? out of /proc/cmdline?
Try this:
Code:

cat /proc/cmdline | grep 'root=' | cut -d' ' -f3
:)

gnashley 06-06-2004 04:21 AM

It has to be more explicit to handle any cmdline order.
I've been greping the small 't' and then '='. This works as long as there is no other small t, for instance in the kernel name.
I thought sed might help but I don't know how to use it.
using grep -d '=' also gets confused.
can sed use a multi character delimiter like 'root=' ?

thegeekster 06-06-2004 04:38 AM

Hmmm...........then see if this is what you want:
Quote:

for i in `cat /proc/cmdline` ; do if [ ! -z `echo $i | grep 'root='` ] ; then echo $i ; fi ;done
:)


All times are GMT -5. The time now is 05:28 AM.