PDA

View Full Version : Terminal-run



Muscovy
06-19-2009, 09:08 PM
Is there a way I can set up my program (outputs a plaintext file into terminal) to run using my_custom_command, versus the filepath?

dwks
06-19-2009, 09:34 PM
I'm not quite sure what you're asking. Are you trying to run a command like "program --dump what.txt" with one command? Or run a program and automatically open it in a terminal?

If you want to automatically add some options to your program, you can create an alias with alias program='program --dump' (that's for bash, for csh I think you just leave out the '='). Add that to your .bashrc (or whatever it's called for your shell) to make it always run on startup. Or you can create a shell script for it; for example:

#!/bin/sh
# This is a comment
# $@ evaluates to all of the arguments passed to the shell script
program --dump $@
Then call that program.sh or something, make it executable with "chmod +x program.sh", and run it with ./program.sh. You can put it into a special directory, e.g. ~/bin, and add that to the path if you want to be able to run the command from anywhere.

Second interpretation: if you're trying to make a command open in a new terminal, so that you can run it from a GUI or something, then consider

$ konsole -e program --dump what.txt
Again, you can alias that or put it into a shell script if you want to.

Remember, if you want less vague answers next time, ask a more specific question. :)

Muscovy
06-19-2009, 09:57 PM
I suppose that was fairly vague. :rolleyes:
I think your first answer is talking about what I want. I'm not too familiar with Linux programming or terminal yet.
I want to be able to type "open myname" or somesuch to open the program. I don't actually know what the open command is. To be more specific, up until now I've been making single executable files. Now I want to do a shell program that something like "sudo apt-get purge myname" or soforth associates with the program in question.

Cactus_Hugger
06-19-2009, 10:09 PM
I want to be able to type "open myname" or somesuch to open the program. I don't actually know what the open command is. To be more specific, up until now I've been making single executable files. Now I want to do a shell program that something like "sudo apt-get purge myname" or soforth associates with the program in question.
I have no idea what that means.
Let me try the hat of divination: I think you're thinking something is magical, when it really isn't. In the command "sudo apt-get purge myname", sudo is the program that is run - sudo is a plain-old honest C program, just like anything you write. For it's argv, it will get passed {"sudo", "apt-get", "purge", "myname"}. sudo will the check that you are a sudo-er, that you can type the password correctly, and if you can, it will raise it's privileges (which it can do because it's setuid root) and then execute the program "apt-get" (also a plain-old honest C (maybe C++ or some other language, I don't know) program, with the arguments {"apt-get", "purge", "myname"}. No card up the sleeves, no magic tricks. sudo just interprets that first argument to be the name of the program. It's just a string - what the string represents is up to the program. To sudo, it's an executable's name/a command to run.

dwks
06-19-2009, 10:16 PM
Well, perhaps "vague" wasn't quite the right word. :p "Rambling", or "irrelevant", or "way-too-easy/way-too-difficult" is more what I was after.

Can you give an actual example, with what your executable is actually called and what you're actually trying to do?

You do know how to run a C/C++ program that you've created, right?

$ cd where/ever
$ gcc program.c -o program
$ ./program
$

Muscovy
06-19-2009, 11:01 PM
Well, perhaps "vague" wasn't quite the right word. :p "Rambling", or "irrelevant", or "way-too-easy/way-too-difficult" is more what I was after.

Can you give an actual example, with what your executable is actually called and what you're actually trying to do?

You do know how to run a C/C++ program that you've created, right?

$ cd where/ever
$ gcc program.c -o program
$ ./program
$
I'm aware of running things like that, yes.
In this case, the program takes a plaintext file and outputs its contents into terminal. The names and locations I haven't determined yet, so let's call the executable "info", and say the plaintext file is called "log" and located in /Documents (~/Documents/log).

Cactus_Hugger
06-20-2009, 11:38 AM
Ok... did you hit post before you finished writing that example?

Perhaps what you're looking for is argv/argc. If I execute a program like so:

$ ./my_program arg1 arg2 arg3
Then it will be passed 4 strings: "./my_program", "arg1", "arg2", and "arg3". These are available from the argc/argv arguments to the main() function:

#include <stdio.h>

int main(int argc, char *argv[])
{
int i;
// argc is how many arguments we've been passed.
for(i = 0; i < argc; ++i)
{
printf("Argument %d: %s\n", i, argv[i]);
}
return 0;
}
^ Compile & run that, and pass it various things. Also, for convience, argv[argc] is always NULL.
Thus, you could run you imaginary program like:

$ info ~/Documents/log
and it's argv[1] would be "~/Documents/log". You could then fopen() that, and do whatever.

Muscovy
06-20-2009, 12:51 PM
The only thing about that is you're adding in an extra word, since ~/Documents/log on it's own would run the file.

Edit: also, I don't quite understand that program.

Cactus_Hugger
06-20-2009, 02:18 PM
The only thing about that is you're adding in an extra word, since ~/Documents/log on it's own would run the file.
Elaborate on whatever you mean here. Following your example, "~/Documents/log" is a "plaintext file" -- presumably a log of some sort, judging by the name you gave it. You can do the following at the terminal:

$ ~/Documents/log
But that will give you an error unless log is an executable, which, if it's a plaintext log file, it probably is not.


Edit: also, I don't quite understand that program.
Did you compile and run it? The program is very simple - it prints out the arguments that are passed to it.

I feel like there is some deeper understanding of something that you've not quite grasped. The main problem I'm having replying to your posts is that you're not giving me a lot of information to work with. If you could, in your next post, take the time to elaborate. Tell us what you are trying to accomplish. Give examples of how it (whatever it is) should work, etc.

Muscovy
06-20-2009, 03:15 PM
In this case, I'm running a compiled executable, so ./info (let's say it's in home) will run the program fine. The program takes the contents of /Documents/log and outputs them in terminal.
I want to know if I can use a nicer command to run this executable instead of ./info, the filepath.
Like sudo, as an example. To do a task with sudo, you don't need to type out the filepath, just plain 'sudo' and whatever the other peramaters are.

And I'll try running the program, but I can't tell what the arguments are, or the significance of it at all.


Edit: Alright, I understand what it does. Counts arguments put in. I must be missing something... why would I use this?

I'm pretty sure the shell script is what I need.


#!/bin/sh
# This is a comment
# $@ evaluates to all of the arguments passed to the shell script
program --dump $@

Though I couldn't get it to do anything. What would be replaced with what? And what is dump?

dwks
06-20-2009, 03:54 PM
Oh, you mean, instead of having to type the "./" in front of "./program", you want to be able to just type "program" as you would run a system program like "sudo"?

That's even easier than you think. You just have to add a directory to your PATH. For example, I usually have a ~/bin directory where I put my own programs that I want to be able to run from anywhere. Then you can just copy (or symlink) your program to that directory. You do also have to add the directory to the path; a command like this will suffice.

$ export PATH=~/bin:$PATH
To avoid having to type that every time you open a new shell, you can put that line into ~/.bashrc (if you're using bash) to have it run every time a new shell launches.

e.g.

~/wherever$ ./program
$ mkdir ~/bin
$ cp program ~/bin
$ export PATH=~/bin:$PATH
$ program
$
Note that what I've described only works for bash. If that doesn't work, try running

cat /etc/passwd | grep $(whoami)
and look at the last part of the line; that tells you what your shell is. Tell us what it says. :)

A shell script can be useful if your program has to be run from a specific directory, for example. Then you could put a shell script like this into your ~/bin:

#!/bin/sh
# This is program.sh, a shell script to run ~/whatever/program from its installation directory.

cd ~/whatever/
./whatever
Shell scripts are really quite simple. They just list a sequence of commands, and the effect of running the script is exactly the same as if you'd typed those commands at the command-line directly.

Let me know if this guess is wrong. :)

My example shell script contained this line:

program --dump $@
That was a hypothetical program. The program's name was "program", and I was passing it the flag "--dump" as well as all other flags passed to the shell script.

Muscovy
06-20-2009, 03:59 PM
This seems to be exactly what I'm talking about. Yay! I'll play around with it and see if I can comprehend it. :D

Is bin folder you're refering to the /bin in filesystem, or is it in a program folder? First makes more sense to me, but the mkdir supports the second.
Edit: Ok, it makes a /bin in wherever the executable is.

I tried it with a simple program called 'reader', and it would execute reader when I launched 'shell'.


./reader
mkdir ~/bin
cp reader ~/bin
export PATH=~/bin:$PATH
reader

However, nothing happens yet when I run just plain 'reader' or shell.

MK27
06-20-2009, 04:20 PM
This seems to be exactly what I'm talking about. Yay! I'll play around with it and see if I can comprehend it. :D

Is bin folder you're refering to the /bin in filesystem, or is it in a program folder? First makes more sense to me, but the mkdir supports the second.
Edit: Ok, it makes a /bin in wherever the executable is.

No, altho it might seem that way because of coincidence. ~ is your home directory. You can make a directory called bin anywhere:

mkdir /tmp/bin

The nice thing about having a bin in your home directory is you can add this to your ~/.bashrc

PATH=$PATH:$HOME/bin
export PATH

That adds ~/bin to the path, but only for you. So now you can throw all your executables in there and bash will find them. Just make sure the names don't conflict with something already in the path! You don't have to call it bin either.

Muscovy
06-20-2009, 04:28 PM
No, altho it might seem that way because of coincidence. ~ is your home directory. You can make a directory called bin anywhere:

mkdir /tmp/bin

The nice thing about having a bin in your home directory is you can add this to your ~/.bashrc

PATH=$PATH:$HOME/bin
export PATH

That adds ~/bin to the path, but only for you. So now you can throw all your executables in there and bash will find them. Just make sure the names don't conflict with something already in the path! You don't have to call it bin either.
PATH being...? Logical guess is, of course, filepath, but filepath=filepath would be utterly redundant. Is it the new run command for the HOME/bin/reader?
Wait, critical problem, I can't get at ~./bashrc. View hidden files doesn't show it, search doesn't, but if I take a new folder and call it .bashrc, it says it's in use.

dwks
06-20-2009, 04:39 PM
PATH is an environment variable. It's a special value that's available to bash and to all processes that bash starts (e.g. your program or sudo!) if they care to look.

The syntax

PATH=~/bin:$PATH
means "take the string '~/bin:' and append the current value of the PATH variable, and put the result back into the PATH variable." In effect, you add "~/bin:" onto the beginning of the PATH variable. If you look at a PATH variable, it might look something like this:

$ echo $PATH
/usr/bin:/usr/local/bin:/bin
As you can see, directories in the PATH are separated by colons. What the command I mentioned does is to add "/home/user/bin" onto the beginning. (Directories are searched in the order they appear, so that this way your programs take precedence over built-in ones.) So after executing "PATH=~/bin:$PATH", you might see

$ echo $PATH
/home/user/bin:/usr/bin:/usr/local/bin:/bin
Where user is your username.

Anyway, got to go. Good luck.

Cactus_Hugger
06-20-2009, 04:43 PM
When you type './my_program', the ./ indicates that my_program is in the current directory. If it were in a subfolder called 'progs', you could type 'progs/my_program'. If you just type, for instance 'sudo', however, the shell has to figure out where this program is. To do this, it searches an environment variable named 'PATH'.

The following:

PATH=$PATH:$HOME/bin
Sets PATH to whatever it was orginally, plus a ':', plus whatever value is in the variable HOME (usually your HOME path), plus '/bin'
In the PATH variable, the paths are separated by a colon. For example, if your path is:

$ echo $PATH
/usr/local/bin:/usr/bin:/bin
So, when I type 'sudo', the shell looks in /usr/local/bin, then /usr/bin, then /bin. (It'll probably find it in /usr/bin.)

You can determine where a particular program is with which:

$ which sudo
/usr/bin/sudo
$ which ls
/bin/ls

Muscovy
06-20-2009, 05:29 PM
I think I understand this. How do I add it to bash? I can't get at it.

MK27
06-20-2009, 06:04 PM
I think I understand this. How do I add it to bash? I can't get at it.

You might as well leave "hidden files" viewable if you are programming, there is not really a need to hide things from yourself.

You may not have a ~/.bashrc by default (but you probably should...). Bash first uses /etc/bashrc, then if a ~/.bashrc exists, it will process that too*. There is also an /etc/profile and a ~/.bash_profile. These serve slightly different purposes (for login and non-login, foreground and background instances of the shell, and profile is used by shells other than bash if they exist) but most stuff can just go in ~/.bashrc.

To make a long story short, look in /etc/skel and see if there is a skeleton .bashrc and .bash_profile there. Those are supposed to be copied into your home directory when it's created; if you can't find one, copy it into there and use that (make sure you "chown me.me .bashrc").

The Linux Documentation Project has a "Bash Beginner Guide", this is from that:
Shell initialization files (http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_01.html)

*actually I am wrong about the order of things here...I think. The order may actually be dictated by the files themselves, which check to see if the "next file in line" exists. Pretty sure bash is hardcoded to read /etc/profile then /etc/bashrc at the very least.

Muscovy
06-20-2009, 08:34 PM
I couldn't see most of the things you're talking about (I can view hidden files, by the way), though I found a folder called profile.d which I believe you mentioned. It contains gvfs-bash-completion.sh .
It's got licensing and a chunk of code, all similar statements. Here's one:


complete -o nospace -F __gvfs_multiple_uris gvfs-ls

Could I put the bash code here?

MK27
06-20-2009, 08:52 PM
Could I put the bash code here?

No, those are shell scripts tho and I believe probably intended to run from one of the files I mentioned earlier. If you really don't have a .bashrc, create one like this


#~/.bashrc

TESTHW="Hello World"
export TESTHW

# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi

That last block I just copied, but I think /etc/bashrc is pretty much a given. Make sure you own it and it is set "chmod 644 .bashrc".

Then just start up a fresh CLI terminal and you should be able to do this:

[root~] echo $TESTHW
Hello World

Muscovy
06-20-2009, 09:01 PM
I ran the script (just called ~bash_create, I assume that's fine), though I don't know how to use terminal as root. The only root login I've used is nautilus.

Edit: Wait... .bashrc... FOUND IT. Oh dear. I can't believe I didn't think of looking for a file. I assumed it would be one of the .name folders.
...opps. Alright, so...



reader=$reader:$username/bin

Where the program is ~/bin/reader?

MK27
06-20-2009, 09:28 PM
I ran the script (just called ~bash_create, I assume that's fine), though I don't know how to use terminal as root. The only root login I've used is nautilus.

whoops, sorry! I didn't mean you had to do that as root. In fact it won't work. You should do that as whoever owns the .bashrc script. You don't have to run it, bash will run it when you open a shell. "echo $some var" is just a command like "printf(this)" where "this" is a character string. When bash runs that .bashrc at startup, it will "export" the variable $TESTHW, meaning you can refer to it on the command-line whenever you are logged in from now on. Those are handy with (eg) compiler switches. But it sounds like you found the actual file...





reader=$reader:$username/bin

Where the program is ~/bin/reader?

No. You just to add your new "bin" to the path:


PATH=$PATH:$HOME/bin
export PATH

There may be a path line in there already, in which case just add ":$HOME/bin" to the end of it.

Now all the executables and links in that directory will be available without a path on the command line (the same as a command) -- but only to whoever owns $HOME/bin and ~/.bashrc.

Try and look at this:
http://tldp.org/LDP/Bash-Beginners-Guide/html/index.html
esp. chapter 3...bash is it's own little arcane world

Muscovy
06-20-2009, 09:51 PM
Ok, to be totally sure I understand this:


PATH=$PATH:$home/bin
export PATH

Looking briefly at that section, I think this is right. This would mean that if you type a word, if it's the name of a file in the HOME/bin (my account is actually just called home), then run that program.

Muscovy
06-20-2009, 09:53 PM
Yes! Thank you to everyone who's helped me!