In most cases, Puppy Linux is built to be easy to use and graphical wherever possible. There are times, however, when using the shell (Bash, commandline, terminal, etc) is necessary, more powerful, or can provide helpful information. I believe some basic knowledge of the shell is advantageous to all computer users, regardless of experience level. Note that I did not single out Linux users here, because I believe that Windows users should learn to use Windows command line too.

If you are putting together a software package or are having trouble running an application, the shell can be very helpful here. Most often, this is a dependency issue when trying to install a new application. I will use this thread to go over some shell basics so that you can solve these kinds of problems. I will also touch on basic shell scripting so that you can learn to add some automation to your software.

We should be using Puppy 4.2.1 (this will work for most versions, but for uniformity, lets use 4.2.1) and we will be putting together the ZynAddSubFx Software Synthesizer package. Trust me when I say that it is a lot less frustrating to learn this when you don't need it, than it will be when you do.Last edited by PupGeek on Fri 02 Dec 2011, 21:33; edited 4 times in total

Ok lets get started. First we need a program to install. I am choosing a software synthesizer called ZynAddSubFx. We will not be using any package manager, as it would defeat the purpose of this discussion. We are learning to use the commandline to diagnose and repair unresponsive programs. We need to find a repository that can be accessed with a browser. For this, I will use the Ubuntu repository. I am using Puppy 4.2 (Kernel 2.6.25.16) for this tutorial so I will go with the Dapper Drake version. You can click below to get there.

Now, we need to create a directory to work in. Choose a location for this directory and name it ZynZddSubFx. Remember where this location is so you can download the software directly to it. When you click on the link above, you will find yourself at a page that organizes packages by type. I have tabbed browsing capability, I recommend opening in new tabs from the context menu instead of simply clicking on items. From this page, click Sound, then scroll down and click ZynAddSubFx. On the ZynAddSubFx page, you should see a list of dependencies. We will be getting all of those, but for now, lets just scroll down and download ZynAddSubFx for i386 (assuming you are using a 32 bit puppy). You should come to a list of mirrors. Choose one and at the dialog, save it to disk, choosing your newly created directory.

Now open up that new directory and you should see the .deb file in there. Right-click anywhere within that window and in the 'window' submenu, choose 'terminal here'. this will open up a shell window for you set for that directory. Verify that you are in that directory by typing 'ls' at the # prompt. You should only see the .deb file you just downloaded. You will be extracting this .deb from the shell, but notice that the filename is rather long and easy to get wrong. We will be using a 'for' loop to help you here. Just type the following in

Code:

# for i in `ls *.deb`; do undeb $i; shift; done
#

I know there was only one file in here but I used a for loop because in many cases, there will be several such files to do and this makes it much easier than typing long filenames. After executing the loop, you should find a usr directory along with the .deb file. Enter the following command in the shell that is opened while noting that I do not use a preceding '/' in the path.

If I had just clicked on an icon, it simply would have appeared unresponsive, so that is one way the shell can help you solve a problem. Now that we know that there is a missing library file, we can try to resolve it. Lets first start by using the ls command (for List) to try and locate it. Enter the following line in the shell:

There is nothing like it there either. This means we will have to download it so lets go back to the ubuntu repo. If you have kept your ZynAddSubFx package page up, you can select libmxml from the dependency list and proceed with downloading it. You may have to keep downloading dependencies until all are resolved and this is why I taught you the for loop. It makes it so much easier. When I get back, we will get to installing and testing our program to see if it works.

Edit: I tried to use the Hardy Heron packages, but I found out they require a newer GLIB, which can cause major problems if updated. I have decided to go with Dapper Drake packages instead.Last edited by PupGeek on Sat 05 Mar 2011, 21:35; edited 4 times in total

Ok now that we have downloaded the missing library libmxml, lets run the for loop once more. This will extract all .debs in the directory. After that run the usr/bin/zynaddsubfx line again and see what happens.

That's right! You get the same error message about the same dependency! This is because we have not installed anything to your system directories ( those contained in the /usr directory ). We could simply copy them over if we'd like, but that can sometimes cause trouble, so I'd like to try a different method. We can use what are called "environment variables". Included in these environment variables are paths and library paths that Puppy is supposed to look in to locate commands and libraries. We can add the current directory to those from the command line, but the changes will disappear when the shell is closed. It is quite a handful to type that in every time we want to test our new program, so we will do this in a "shell script". A shell script is a text file that contains shell commands to be executed. Nearly all these commands are identical to typing them into the shell yourself. It adds convenience by executing all the commands within from just a single command. Let's begin by creating a new script called "Run" in your ZynAddSubFx/usr directory. Right click anywhere in the directory window, then in the "new" submenu, choose "script". When done, right click on it and "open as text".

As you can see, you have a blank page with the text "#!/bin/sh" as the first line. All shell scripts must begin with this line, as it identifies the shell to use for the script. Place your cursor at the end of that line and press enter a couple of times. We will begin by defining variables, including environment variables. Edit your new script so that it appears as below:

# Note the format PATH=$PATH:$APPDIR/bin. This format defines PATH as the existing PATH appended by APPDIR/bin
# It is important that you include the existing PATH in the new definition so as not to overwrite what was already #there.
# Also note that after being defined, all variables being used must be preceded by $.

# Now that our variables have been defined, let's try running the program

$APPDIR/bin/zynaddsubfx

Any text preceded by '#' within the script is called a comment and is placed there to help the user understand the script better. It is important to insert many comments as it can clarify the commands and why they are in the script.

Now enter your ZynAddSubFx/usr directory and open a new terminal there and type './Run' to run your new script and see what happens. Now its calling for libfltk. This means that it has now found the first dependency and that using the environment variables worked. Now it is missing another dependency. Lets download the fltk (pronounced "full tick") package and run the for loop in the old shell again. You may have to keep repeating this sequence until all dependencies are resolved, so I won't go over it again.Last edited by PupGeek on Sun 06 Mar 2011, 14:25; edited 8 times in total

Ok, when all dependencies are resolved, you should get a gui for ZynAddSubFx. The first screen should offer you a choice of beginner or advanced interfaces -- choose one. If you click on the "VK" button it should bring up a virtual keyboard so that you can start playing notes (either by clicking on the virtual keys or by pressing keys on your computer keyboard). You should, at this point, hear something. Now, you might think we are done, but we are not. Try clicking on the 'instrument' menu and then 'show instrument bank' to see what happens. That's right, its blank and no matter how many times you refresh it, it stays blank. We will now solve this problem. We will further edit your 'Run' script to accomplish this. The beauty of packaging software like this is that, with a script you can redefine environment variables, place items in any directory and remove them when done. Nice and clean.

# Now that our variables have been defined, let's try running the program
$APPDIR/bin/zynaddsubfx

rm /usr/share/zynaddsubfx #And this line too

Now type ./Run again and see what happens. This time, when you click on the 'instrument' menu and 'show instrument bank' you can refresh it and get some options in the drop down menu. For now, select an option and play around with it. We are still not done yet.Last edited by PupGeek on Sat 05 Mar 2011, 22:42; edited 1 time in total

Ok, as I said, we still aren't done yet. Assuming that you are using Rox to navigate through directories, we are going to make this into a "Roxapp". A Roxapp is a directory that is linked to a script (called AppRun). When you click on this directory, it executes that AppRun script. Now right click on your 'Run' script and rename it to 'AppRun'. Now first, type ./AppRun into the shell and notice what happens. That's right, the same thing as when it was named 'Run'. Close or minimize the shell and back out of the directory containing your 'AppRun' script and notice that the icon for the usr directory has changed. Click on that icon. Now try to show your instrument bank and see what happened. It's back to being blank again. This is due to some code in the script. When we wrote the script, you may have noticed some strange stuff like `dirname "$0"` and `pwd`. These are examples of "Command Substitution". Command substitution is like a variable defined by the output of a particular command, and is placed in between backticks (`). You have seen an example of this in the 'for' loop we ran while installing dependencies (for i in `ls *.deb`). The command dirname "$0" is the current directory that the shell happens to be in (.). Unfortunately, you cannot use it when creating a symbolic link, as it doesn't work correctly. The command pwd is the present working directory, where you accessed the script. When you typed ./AppRun into the terminal, everything worked fine because `pwd` was the same directory in which the script was. When you clicked on the directory's icon, It failed because `pwd` was one level up and so the link was made incorrectly. Now how do we solve that? Well one idea is to use a full path, but we can do better than that, and make it a lot neater too. I will explain it further in my next section, but for now, lets give your Roxapp a new icon. Right click on your roxapp and 'look inside' it go to share then pixmaps and notice the icon and right click on it and select Copy. Remove the share/pixmaps/ from the path shown in the Copy dialog, and navigate back to the usr directory and you should see a copy of the icon. Right click on zynaddsubfx.xpm and rename to .DirIcon and it should disappear. In the meantime, rename your AppRun script back to Run so you will not run the script if you enter the usr directory again. If you click on the Eye in your toolbar, it should display hidden files, including your new .DirIcon file. When you navigate back out of your usr directory you should find that it has the new icon you just gave it.Last edited by PupGeek on Sat 05 Mar 2011, 23:16; edited 2 times in total

Ok reenter your ZynAddSubFx/usr directory and we will now attempt to place all of its directories into a "squashfs" file. A squashfs is a compressed filesystem that is sort of like a tar.gz file. Unlike a tar.gz archive, a squashfs can be mounted and accessed without extracting its contents. This is a very useful feature and essential to all LiveCD Linuxes. You may have seen examples of this as .sfs modules for puppy. I like to use them in Roxapps because it makes them very neat and allows for absolute control over where directories are located, making the creation of links much more reliable (I call them Hassle-Free Roxapps because in making them, I try to resolve all dependencies). I know that we still have that issue with the instrument bank but this process should end up resolving that.

Lets begin our conversion by creating a new directory in ZynAddSubFx/usr. Lets call it ZynAdd. Move or copy your bin, lib, and share directories into it. If you moved them and try running your script now, it won't work. Close all your old terminals and open a new one in ZynAddSubFx/usr. Type the following line into the terminal:

Code:

mksquashfs ZynAdd ZynAdd.roxfs

You should see a progress bar as it is creating the file and a bunch of verbose text when completed. After completion you should see a file named ZynAdd.roxfs. You can name the file and extension to your choice directly in the mksquashfs command. I like to use roxfs as the preferred extension for my roxapps. With that completed, we will now get to editing the 'Run' script to utilize the new roxfs.

export APPDIR=/mnt/ZynAdd # This defines the variable APPDIR as the working directory
export PATH=$PATH:$APPDIR/bin # PATH and LD_LIBRARY_PATH are environment variables
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$APPDIR/lib

# Note the format PATH=$PATH:$APPDIR/bin. This format defines PATH as the existing PATH appended by APPDIR/bin
# Also note that after being defined, all variables being used must be preceded by $.

ln -s $APPDIR/share/zynaddsubfx /usr/share # creates a link

# Now that our variables have been defined, let's try running the program
$APPDIR/bin/zynaddsubfx

rm /usr/share/zynaddsubfx
umount /mnt/ZynAdd # This unmounts the roxfs after use
rmdir /mnt/ZynAdd # Cleans up after itself

Now rename the script back to 'AppRun', back out of the directory and click on the icon to test it out.

If it is working, you may rename the directory from 'usr' to ZynAddSubFx, look inside it, and delete the ZynAdd folder, since it now uses the .roxfs instead. Notice that when it is not running, you will not find any evidence of it having been in your /usr or /mnt directories. If it crashes, however, the script never completes and directories and links will remain where they were placed and will have to be removed manually. I have now taken you from knowing nothing about the shell to making a Hassle-Free Roxapp. I hope this inspires you to learn more about the shell and scripting. It can place a lot of power in your hands. Good luck and enjoy.

PupgeekLast edited by PupGeek on Sun 06 Mar 2011, 00:26; edited 4 times in total

If anybody here wishes to share other tips regarding the shell and scripting please feel free to post them here. This is intended to introduce beginners to the shell and scripts so that they may begin experiencing the true power of Linux.

I recommend downloading some additional materials such as what I am posting below for explanations of the commands being used here, and to help make your experience more predictable.

This thread was made with the intention of getting more enjoyment out of Linux. Let's keep it respectful and beginner-friendly. Have fun Last edited by PupGeek on Sun 06 Mar 2011, 10:41; edited 2 times in total

@jpep: Good point, but with the way I discussed creating a new script, it does that automatically. Anyway, for those who create a new script from within a text editor, you can use the chmod command, or right click > Properties to set exec privileges.

The chmod command to make a script executable is as follows:

Code:

chmod 755 <filename.ext>

Last edited by PupGeek on Sun 06 Mar 2011, 19:08; edited 1 time in total

This is not intended to be a complete programming introduction, it was meant to help people solve a problem they might have. As for the preceding "./" I did not want to be confusing people this early in the game ( "./" and "/" would look a bit too similar to me, at a glance, if I were a beginner). I had to be obvious because I wanted to be as concise as possible, as it was long-winded enough.

I do not enclose variables in quotes, because my experiences with earlier versions of BASIC yielded a lot of syntax errors due to that. I am trying to gently guide beginners to using the CLI, and make something work, not to enforce proper coding convention.

Honestly, I do not have a single problem with using ls in a command substitution. In fact, I have more problem with the inclusion of spaces and newlines in filenames, as, I feel, that is more against naming convention. When it comes to naming files, I like to treat spaces and newlines as illegal characters myself. Instead I use CamelNotation and dashes.

If the beginner becomes interested enough in coding, they can learn all about coding conventions. This is intended to be more of a survival guide -- a way to possibly fix a program that doesn't seem to execute. I only threw in making the roxapp so that the beginner could learn by making something work, rather than throw a bunch of text and rules at them.Last edited by PupGeek on Sun 06 Mar 2011, 14:50; edited 1 time in total

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot vote in polls in this forumYou cannot attach files in this forumYou can download files in this forum