ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I have a question about a sh script and hope one of you can help.
Say I have a file called "script.sh" it looks like this:
Code:
#!/bin/sh
for file in first_file; do
cp $file SAVED/$file
done
Now I want to change this script to something like:
Code:
#!/bin/sh
for file in BLANK; do
cp $file SAVED/$file
done
and then run
script.sh -file first_file
And let the script fill "first_file" in the BLANK space.
(OR maybe it can be done much easier: how can I let the script know that I want it to fill in the word "first_file" everywhere in the script were it says "file")
Two things:
a) I have no idea if this is at all possible in sh
b) of course my real script is much more complex, but getting an option like I describe above would make my work a lot easier.
c) my real script should really stay in sh (so I'm bound to sh)
Is this question clear? (I could imagine not...)
Please share any thoughts and ideas,
You can just pass the name of the file as argument, then use positional parameters:
Code:
#!/bin/sh
for file in $1
do
cp $file SAVED/$file
done
If you have a list of files passed as a list of arguments separated by spaces:
Code:
#!/bin/sh
for file in $*
or
Code:
#!/bin/sh
for file in $@
See the Advanced Bash Scripting Guide for a complete explanation about positional parameters and the difference between $* and $@. If you really want to use options like -f or --file, you have to go through getopt or getopts.
What colucix means by "pass the name of the file as an argument", is like so (assuming your script is named script and the file is called filename:
Code:
shell$ ./script filename
So, you've passed filename to the script, as the first argument. Basically, anything following the name of the script, is an argument or an option. Each one will be allotted to a successive shell variable (the positional parameters), so:
Code:
shell$ ./script hello goodbye rotten
passes 3 arguments to the script, which will be available within the script as $1, $2, and $3, while $0 is reserved for the script itself.
Well, colucix' second example is the way I usually do:
Code:
for stuff in $*; do
echo $stuff
done
That will loop through the space-separated arguments you gave on the command-line. Is that what you want?
It is pretty cool this bash/cli stuff. The term I like that describes the myriad linux command-line & bash tools is, "Elegantly Simple" though there are certainly no shortage of "Elegantly Ridiculously Complicated" tools too
Sasha
PS- Nope, I don't mind. That's why we're all hanging around here-- to help each other out
TEMP$ ls
first_file.txt SAVED script.sh
TEMP$ cat script.sh
#!/bin/sh
for file in $1
do
cp $file SAVED/$file
done
TEMP$ sh ./script.sh first_file.txt
TEMP$ sh script.sh
TEMP$ ls -l SAVED/
-rw-r--r-- 1 kdijk cnl 5 Sep 9 23:41 first_file.txt
TEMP$
Now, it is keeping in mind that I have passed "first_file.txt" to "script.sh". I was wondering what I should type if I want to retrieve what I've passed through to the script?
(It seems that that last piece of text did not do that... should it?)
OK, your script appears to be working, but I don't understand your question
If you're asking, "How can I retrieve the argument I gave the script, after the script is done executing?" then the answer is, "I don't believe you can."
Once the script is run and done, its variables and things like that are gone into outer-space. With each execution, you can pass new stuff to it, and that stuff will only effect the environment of the running script itself. Once it's finished, that's it.
Did this answer the question? If not, please rephrase
Sasha
PS - I shouldn't say there's NO WAY to get that info, but I'm fairly certain there's not; if there IS a way, I don't know it.. I'm far from expert with bash either; just learning as I go
Last edited by GrapefruiTgirl; 09-09-2009 at 11:00 PM.
Well, colucix' second example is the way I usually do:
Code:
for stuff in $*; do
echo $stuff
done
That will work just fine until you have any spaces in the file names, for example if
Code:
c@CW8:/tmp/tmp$ /bin/ls -l
total 4
-rw-r--r-- 1 c c 0 2009-09-10 17:15 a file name with spaces in it
-rwxr--r-- 1 c c 112 2009-09-10 17:19 my.sh
c@CW8:/tmp/tmp$ cat my.sh
#!/bin/bash
for stuff in $*; do
echo 'using $*' $stuff
done
for stuff in "$@"; do
echo 'using $@' $stuff
done
c@CW8:/tmp/tmp$ ./my.sh *
using $* a
using $* file
using $* name
using $* with
using $* spaces
using $* in
using $* it
using $* my.sh
using $@ a file name with spaces in it
using $@ my.sh
That will work just fine until you have any spaces in the file names, for example if
Code:
c@CW8:/tmp/tmp$ /bin/ls -l
total 4
-rw-r--r-- 1 c c 0 2009-09-10 17:15 a file name with spaces in it
-rwxr--r-- 1 c c 112 2009-09-10 17:19 my.sh
c@CW8:/tmp/tmp$ cat my.sh
#!/bin/bash
for stuff in $*; do
echo 'using $*' $stuff
done
for stuff in "$@"; do
echo 'using $@' $stuff
done
c@CW8:/tmp/tmp$ ./my.sh *
using $* a
using $* file
using $* name
using $* with
using $* spaces
using $* in
using $* it
using $* my.sh
using $@ a file name with spaces in it
using $@ my.sh
Right! In which case (off the top of my head) there are two solutions (or a combination of two things):
1-- use quotes around the "stuff"
2-- use some delimiter between the filenames, and parse the input.
@ catkin -- what would you do in this case?:
Code:
filename1="this one has spaces"
filename2="thisonedoesnot"
shell$ ./script this one has spaces thisonedoesnot
without actually running this example, I think $@ will not work. However, the following does work:
Code:
filename1="this one has spaces"
filename2="thisonedoesnot"
shell$ ./script "this one has spaces" "thisonedoesnot"
So, it's annoying having to quote all the arguments -- what to do?
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.