LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Blogs > rainbowsally
User Name
Password

Notices


Rate this Entry

More Tooling Up Stuff

Posted 12-19-2012 at 11:52 AM by rainbowsally
Updated 08-06-2014 at 09:30 AM by rainbowsally (skip rant, typo correction)

About the commandline

Today's features:
  • Why the commandline rocks and GUI apps have rocks in their heads at times.

You can skip this somewhat rambling rant by going down to "CONTINUE" below.

[Note for KDE users: Konqueror has a nice konsole terminal that can be opened with F4. It's much MUCH better than Dolphin, if you're a programmer. See recent blog including 'launch' and shell-exec if you have trouble executing these files when you click on them or press ENTER.]

It's especially clear in linux (where the core utilities and other executables are accessible to gui applications) that gui's are mostly just a way to do your typing for you.

This may seem like a controversial statement, but when you think of apps like kdbg (my favorite debugger -- excellent job KDE!) or other linux 'gui front ends'.

But it's even true of Windows where you CAN'T talk to the elemental blocks of the system directly except through possibly 'rundll'.

The commandline gives you access to things not anticipated by the one-size-fits-all officianados that seem to be running amok and taking over My Computer with Their Predilections. (Is Resistance Few-Tile?)

Two more quick points and I'll get to the fun stuff: If you have KDE open a terminal and type kwrite /etc/fstab. WHAT'S ALL THAT CRAP ABOUT? And why don't the expect anyone to see it? (My favorite is the kxmlguiclient error message about not having removed the object from the factory before deleting it, which is done in the very code that DOES remove it before deleting it -- see kxmlguiclient.cpp around line 100 in the kde sources.)

And the other point is easier to demonstrate. Open a task manager (ksysguard in kde) and watch the PIDs change. In KDE, every thirty seconds, the KPackageKit is relaunching itself, playing dodgeball with hackers, apparently, and leaving a backdoor into your system that is utterly out of our control which can be and is used by developers every time they discover they SCREWED UP YOUR COMPUTER, which they can fix anonymously. And by which means they can insert any kind of opaque (non open) code they like -- also anonymously. And that's where I'll leave this rant for the moment though this ia s HUGE issue of a nature that the free software foundation has been aware of for years, though they haven't identified all the ways it's done. See GPL v. 3 around line 50. And there's no way in the world open???SUSE could be in compliance with the "open source" requirements, since half their source downloads are NOT what's in our systems. (Is libffi still a 62 meg download? It should be 280K or thereabouts.)

With all this talk about "security" going on, who is our system supposed to be secure from? From us? The owners of the computers? We at least know our own names.

CONTINUE....

Now with that to set the stage for this blog entry, what I want to talk about now is "what's a dialog"?

Is a "dialog" in a normal conversation with your friends simply Yes/No/Cancel?

I hope not!

And on the commandline we can see interesting tips, helps, or maybe even crashes that WILL tell us a heck of a lot more than we get from Yes/No/Cancel and a silent blinking out of an application with no clue as to what happened or why.

So why not create our own commandline tools. Let's have a dialog with the operating system where WE give the orders and it decides Yes/No/Cancel. We'll consider a crash to be the machine's way of saying "Cancel".

And For Today's Exciting Adventure In Computer Mad Science...

Assuming you have ~/bin in your path (a requirement for experimenting safely), we can create the simplest of installers, one that simply inserts a symlink to an application in that folder without changing the location of the application. Try that in Windows! No, you have to make a registry entry so the os can find it. You can make a link file, sure enough but it won't work right in all cases because it's not a pointer to the real file.

Here's the application I use to make these symlinks. The syntax is:
Code:
new.symlink <appname> <folder>
file: $HOME/bin/src/rs-tools/new-funcs/new.symlink
purpose: utility (executable)
Code:
#!/bin/sh
#new.symlink <FileInCurrentDir> <NewLinkLocation>

if [ $# != 2 ];then
    echo "Usage: new.symlink <FileInCurrentDir> <NewLinkLocation>"
    exit
fi

file="$PWD/$1"
dir="$2"

(cd $dir && ln -sf $file .)
As you can see it's a script. What you can't see is that once it's 'installed' itself like this
Code:
./new.symlink new.symlink ~/bin
it can be used anywhere to install anything and the script itself can be edited any time you want to modify it, by it's address in the ~/bin folder. That is, to edit it you type 'edit ~/bin/new.symlink' and don't even have to go hunt it down.

You can put it anywhere you like but I keep my sources for stuff like this under ~/bin/src so it's not hidden but it's also not up there in my face every time I look at my home directory.

So now with the ability to make a new.symlink, how about making a new.main.

This is likely to save you quite a bit of typing over time, and these templates can be edited without having to use a specialized tool to do it. The templates are the files themselves.

The key to this one's cool features is the 'readlink' shell command. It's a coreutil. Nothing special or magical about it.
file: new.main
purpose: utility (executable)
Code:
#!/bin/sh

HERE="$PWD"

APPPATH=`readlink -f "$0"`
THERE=`dirname "$APPPATH"`

FMTLIST=

cd "$THERE"
for i in `ls formats/*.* 2>/dev/null`; do
  FMTLIST=`printf "%s\n%s" "$FMTLIST" "$i" | sed '/^$/d; s|^.*/||; s|\..*||;'"  "`
done
cd "$HERE"

print_types()
{
echo "
Available main file formats:

$FMTLIST
"
}

print_usage()
{
  cat "$THERE"/new-main.hlp
}

if [ "$1" = "" ]; then
  print_usage
elif [ "$1" = "--help" ]; then
  print_usage
elif [ "$1" = "--types" ]; then
  print_types
else
  TYPE=`echo "$1" | sed 's|\.*||'`
  NAME=`ls "$THERE"/formats/$TYPE.*`
  EXT=`echo "$NAME" | sed 's|^.*\.||; s|^.*\.||'`
  cp "$THERE"/formats/$TYPE.* "$HERE"/main.$EXT
fi

if [ "$2" != "" ]; then
  mv main.$EXT $2  
fi
And I put that one in my $HOME/bin/rs-tools/new-funcs folder as well.

There is a help file in the directory along with new.main. It doesn't contain the help itself. It just types out the help text that is in the 'THERE' directory.

Here's the help file.
file: new-main.hlp
purpose: docs
Code:
Usage:
  new.main [ <type> [filename] | --help ]
  
  Creates a new main c or c++ file of a type determined by
  <type>.  If you wish to give it a name other than main.<type>
  add the filename for the resulting file.
  
  To see a list of file types available type 
    new.main --types
  
  To see this help type
    new.main --help
The help file can be edited with a text editor as new features are added or removed and it will always be current.

Now here's the coolest part.

The folder 'formats' is just as modifiable and just as current as the help doc.

If you add files, they will show up in the --types listing. If you remove them, they will disappear. And once you have a file that you want to use as a skeleton for new "main" files (or any other source file) you can add it to the formats folder and it will be available for use immediately.

I'm about to add some new formats to this myself, so I'm showing this while it's still simple. ;-) [I may also change it so it doesn't clobber any existing 'main.*' in the folder it's writing to when it's supposed to create something with a name other than 'main.*'. But this one does have that bug. And it shouldn't be too hard to fix. Good luck! :-) ]

file: formats/c.c
purpose: source file
Code:
// main.c -- skeleton created by new.main

#include <stdio.h>
#include <malloc.h>
#include <string.h>
void dbg(){} // for a non-moving breakpoint


int main(int argc, char** argv)
{
  dbg();
  // add routines here
  return 0;
}

file: formats/cpp.cpp
purpose: source file
Code:
// main.cpp -- skeleton created by new.main

#include <stdio.h>
#include <malloc.h>
#include <string.h>

void dbg(){} // for a non-moving breakpoint

int main(int argc, char** argv)
{
  dbg();
  // add routines here
  return 0;
}

file: formats/ftl.cpp
purpose: source file
Code:
// ftl main.cpp -- skeleton created by new.main

#include "ui.h"

// shotgun load some commonly needed headers
#include <ftl/run.h>
#include <ftl/Window.h>
#include <ftl/error.h>
#include <ftl/events.h>
#include <ftl/util/WindowTool.h>
#include <ftl/rgbImage.h>
#include <ftl/SharedImage.h>
#include <ftl/util/filename.h> // filename_size()
#include <ftl/ask.h>
#include <ftl/util/path_utils.h>
#include <ftl/util/filename_load_save.h>

// and some commonly used c headers
#include <stdio.h>    // printf, sprintf, etc.
#include <stdlib.h>   // exit()
#include <unistd.h>   // tons of stuff
#include <malloc.h>   // memory allocation
#include <string.h>   // strings and block comparisons and moves
#include <ctype.h>    // ispunct()

void dbg(){}          // a breakpoint for kdbg.exec

using namespace ftl;

// additional funcs and vars here

int main(int argc, char** argv)
{
  dbg();
  
  // register_images(); // for SharedImages if used.
  Window* w = make_window();
  w->show();
  // add more init stuff here..
  
  return run();
}

file: formats/qt4.cpp
purpose: source file
Code:
// qt4 main.cpp -- skeleton created by new.main

#include <QApplication>

// #include "form.h"
// #include "ui_form.h"
// #include <stdio.h>
// LD_LIBRARY_PATH=/opt/qt4-dbg/lib:$LD_LIBRARY_PATH

void dbg(){}

int main(int argc, char *argv[])
{
  dbg();
  
  // this sets the global qApp instance
  new QApplication (argc, argv);
  
  // replace and/or add additional setup stuff here.
  // Form w;
  // w.show();  
  // Reposition, resize etc. here after shown()
  
  return qApp->exec();
}
To list all the 'new' funcs you can create, all you need to do is type
Code:
ls ~/bin/new.*
Or you could create a utility to list them for you, like this.

file: new.listall
purpose: utility (executable)
Code:
#!/bin/sh 

#pushd ~/bin >/dev/null
#b=`ls new.*`
#popd >/dev/null
# you may not have pushd/popd so...
get_names() { (cd ~/bin && ls new.*;) }
b=`get_names`

a=`printf "%s" "new.<name> creates a new set of project files.
Currently available functions are:
"`

c="$a
 
$b"

if ! kdialog -msgbox "$c"; then
xmessage -center "$c"
fi
Here's a screenshot of mine. As you can see, I don't like typing that much either.Look at all the stuff I can create with new.*

http://rainbowsally.org/rainbowsally...ew-listall.png

But neither does it make sense to cut off my fingers when sometimes it does make things a LOT easier by just typing a word or two.

Need a new image file? Here's 'new.image'. Create a folder in the same directory with the app named "image-formats" and fill it with with blank 32x32 image files named a.png, a.jpg, etc. and create a help file named new-image.txt. The images will automatically be included in the types list.

file: new.image
purpose: utility (executable)
Code:
#!/bin/sh

HERE="$PWD"
APPPATH=`readlink -f "$0"`
THERE=`dirname "$APPPATH"`

FMTLIST=

cd "$THERE"
for i in `ls img-formats/a.* 2>/dev/null`; do
  FMTLIST=`printf "%s\n%s" "$FMTLIST" "$i" | sed '/^$/d; s|^.*/a\.||;'"  "`
done
cd "$HERE"

print_types()
{
echo "
Available image formats:

$FMTLIST
"
}

print_usage()
{
cat "$THERE/new-image.txt"
}

if [ "$1" = "" ]; then
  print_usage
elif [ "$1" = "--help" ]; then
  print_usage
elif [ "$1" = "--types" ]; then
  print_types
else
  EXT=`echo "$1" | sed 's|^.*\.||'`
  cp "$THERE"/img-formats/a.$EXT "$HERE"/$1
fi
As you can see, the file above is fairly similar to the new.main file except that it gets the listing a little differently and the file names are all 'a.<ext>'

I want to toss one more out there. This uses 'kate' with the '-n' switch so it launches a new 'kate' session and it will parse output from 'grep -n' output and from gcc errors to open to the exact line.

file: edit
purpose: utility (executable)
Code:
#!/bin/sh

# change first ':' to a --line switch and replace next colon to end of the arg with a blanks
args=`echo $@ | sed 's|[:]| --line |; s|[:].*| |g;'`

# if it's single colon --line will have no parameter, so we'll remove it
args=`echo $args | sed 's| --line$||'`
launch "kate -n $args"
That app can save you a lot of time, even though you have to type a couple a four letter word which I occasionally really do want to do. ;-)

- The Computer Mad Science Team

:-)
Posted in Uncategorized
Views 691 Comments 0
« Prev     Main     Next »
Total Comments 0

Comments

 

  



All times are GMT -5. The time now is 08:16 PM.

Main Menu
Advertisement
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration