LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   How do I make these shell scripts with ash as my shell? (https://www.linuxquestions.org/questions/programming-9/how-do-i-make-these-shell-scripts-with-ash-as-my-shell-4175421802/)

riahc3 08-13-2012 02:12 AM

How do I make these shell scripts with ash as my shell?
 
Hello

I want to make two shell scripts but they shell scripts isnt exactly my language :P

The following is all pseudocode
The first script will run every say 5 minutes:

Code:

if /tmp/media/sda1 exists or /tmp/media/sda2 exists or /tmp/media/sda3 exists or /tmp/media/sda4 exists
then do
        variable storage=what ever above first returns true (lets say /tmp/media/sda3)
        //storage=/tmp/media/sda3
        if storage+"/"+.runmescript exist
        then do
        ./runmescript
        end if
end if

thats the first one.

Now we have on the harddrive a file called "someconf" at /etc/ also at /tmp/media/sda3 we have a file called "update". someconf has a line that says "dot=99" while update has a line that says "dot=11"

".runmescript" would be.


Code:

load /etc/someconf
    search for "dot=99" in /etc/someconf
          load /tmp/media/sda3/update
            search for "dot=11"
            replace line from update in somesonf
save

how can i do this? thank you!

cortman 08-13-2012 09:15 AM

Code:

#! /bin/ash

volume=$(ls /tmp/media | grep sda[1|2|3|4])

if [ -n $volume ]
then do blah blah blah

And then I get stuck on the +"/"+runmescript. ??

Can I ask exactly what you're trying to do? Please be specific.

riahc3 08-14-2012 01:57 AM

Quote:

Originally Posted by cortman (Post 4753117)
Code:

#! /bin/ash

volume=$(ls /tmp/media | grep sda[1|2|3|4])

if [ -n $volume ]
then do blah blah blah

And then I get stuck on the +"/"+runmescript. ??

Can I ask exactly what you're trying to do? Please be specific.

Crontab will be running this script every x minutes.
If it detects sda1/sda2/etc, it will check if on that volume "runmescript" exists. If it exists, it will run it.

runmescript will scan the local hdd for a file named "conf". If it exists (it will always exist but just in case this check is neccesary) Inside "conf" there will be a line similar to "number=99". runmescript will have a variable named "$numberreplacement=11". When runmescript is ran, it will overwrite the value in conf of "number=99" to "number=11" and save the file (conf). Once it is ran, to avoid further writing and overwriting the same thing over and over, the script will delete itself and/or will unmount the usb device from which it ran from.

Please if anymore doubts, ask :) Thanks for the help.

David the H. 08-14-2012 07:45 AM

If you want to write a shell script, find yourself a good scripting tutorial or two and start working at it. Don't expect us to do all the work for you.

Here are a few useful bash scripting references, I recommend starting with the first link, or perhaps linuxcommand.

http://mywiki.wooledge.org/BashGuide
http://mywiki.wooledge.org/BashFAQ
http://mywiki.wooledge.org/BashPitfalls
http://wiki.bash-hackers.org/scripting/newbie_traps
http://www.linuxcommand.org/index.php
http://tldp.org/LDP/Bash-Beginners-G...tml/index.html
http://www.tldp.org/LDP/abs/html/index.html
http://www.gnu.org/software/bash/manual/bashref.html
http://wiki.bash-hackers.org/start
http://ss64.com/bash/

However, in order to write your scripts specifically for ash, you'll have to limit the contents to only syntax that it can understand, that is, avoid using anything outside of the POSIX standard.

This link has a good breakdown of commands that are specific to bash, and their POSIX equivalents.

http://mywiki.wooledge.org/Bashism

cortman 08-14-2012 08:15 AM

OK, script A:

Code:

#! /bin/ash

volm=$(ls /tmp/media | grep "sda[1|2|3|4]" | head -n1)

if [ -n $volm ] ; then
        if [ -a /tmp/media/$volm/runmescript ]; then
                /tmp/media/$volm/runmescript ;
        else
                echo "runmescript does not exist!"
        fi
else
echo "The target volume does not exist!" ;
fi

I tested this with bash, so test first to make sure it works with ash.

Quote:

Now we have on the harddrive a file called "someconf" at /etc/ also at /tmp/media/sda3
This file is always on sda3? In that case your current script (which looks for sda1,2,3 or 4) will not work if sda1 and 2 are not present. Please clarify. Or better yet, write it yourself. :) Since now you've gotten somewhat of an idea.

ntubski 08-14-2012 11:37 AM

Quote:

Originally Posted by cortman (Post 4753892)
volm=$(ls /tmp/media | grep "sda[1|2|3|4]" | head -n1)

I think that should be
Code:

grep 'sda[1234]'
#or
grep -E 'sda(1|2|3|4)'


cortman 08-14-2012 12:29 PM

Quote:

Originally Posted by ntubski (Post 4754003)
I think that should be
Code:

grep 'sda[1234]'
#or
grep -E 'sda(1|2|3|4)'


*facepalm. The way I wrote it worked; but there's no need for the pipes in a bracket. Thanks for the clarification!

unSpawn 08-14-2012 04:29 PM

Quote:

Originally Posted by cortman (Post 4754029)
*facepalm. The way I wrote it worked;

Apart from the useless use of head, in the Wooledge links David the H. provided there's a page about not using 'ls' ;-p

Ash doesn't have Bashisms like "/tmp/media/sd{1..10}" so in Ash you could:
Code:

#!/bin/ash
BASE="/tmp/media"; n=1; while [ $n -le 10 ]; do dev="sd$n"
 [ -d "$BASE/$dev" ] && { [ -x "$BASE/$dev/runmescript" ] && /tmp/media/sd$n/runmescript; } \
 || n=$(($n + 1))
done
exit 0


cortman 08-14-2012 05:03 PM

Quote:

Originally Posted by unSpawn (Post 4754204)
Apart from the useless use of head, in the Wooledge links David the H. provided there's a page about not using 'ls' ;-p

Ash doesn't have Bashisms like "/tmp/media/sd{1..10}" so in Ash you could:
Code:

#!/bin/ash
BASE="/tmp/media"; n=1; while [ $n -le 10 ]; do dev="sd$n"
 [ -d "$BASE/$dev" ] && { [ -x "$BASE/$dev/runmescript" ] && /tmp/media/sd$n/runmescript; } \
 || n=$(($n + 1))
done
exit 0


Keep the comments coming. That's an intriguing way to do it.

ntubski 08-14-2012 07:25 PM

Quote:

Originally Posted by unSpawn (Post 4754204)
Apart from the useless use of head

Why is the head useless? If 2 or more of the directories exist you need to select only a single one, no?


Quote:

Ash doesn't have Bashisms like "/tmp/media/sd{1..10}"
It does have globbing though, right?
Code:

for volm in /tmp/media/sda[1234] ; do
    [ -e "$volm" ] || break    # we don't have nullglob

    [ -x "$volm/runmescript" ] && "$volm/runmescript"
    break
done

Tested in dash.

unSpawn 08-14-2012 07:55 PM

Quote:

Originally Posted by ntubski (Post 4754271)
Why is the head useless? If 2 or more of the directories exist you need to select only a single one, no?

I should replace "useless" with inefficient: you don't need to fire up external binaries until you've exhausted what your shell provides you with. And even then you can prefer to use builtins like "break".


Quote:

Originally Posted by ntubski (Post 4754271)
/tmp/media/sda[1234]

Sure it's "[]" and not "{}"? Here's "eval echo /tmp/media/sda{1..4}" in a few shells BTW:
Code:

sh: /tmp/media/sda1 /tmp/media/sda2 /tmp/media/sda3 /tmp/media/sda4
bash: /tmp/media/sda1 /tmp/media/sda2 /tmp/media/sda3 /tmp/media/sda4
zsh: /tmp/media/sda1 /tmp/media/sda2 /tmp/media/sda3 /tmp/media/sda4
ksh: /tmp/media/sda1 /tmp/media/sda2 /tmp/media/sda3 /tmp/media/sda4
tcsh: /tmp/media/sda1..4
csh: /tmp/media/sda1..4
ash: /tmp/media/sda{1..4}
bsh: /tmp/media/sda{1..4}
jsh: /tmp/media/sda{1..4}
busybox ash: /tmp/media/sda{1..4}


ntubski 08-14-2012 09:05 PM

Quote:

Originally Posted by unSpawn (Post 4754282)
I should replace "useless" with inefficient: you don't need to fire up external binaries until you've exhausted what your shell provides you with. And even then you can prefer to use builtins like "break".

Meh, if you want efficient don't use a shell script.

Quote:

Sure it's "[]" and not "{}"?
Yes, "{}" is brace expansion which isn't specified by POSIX; "[]" is globbing which is.

Quote:

Here's "eval echo /tmp/media/sda{1..4}" in a few shells BTW:
What's that? A useless use of eval? :p

Here's "echo /tmp/media/sda[1234]" in a few shells:
Code:

% mkdir -p /tmp/media/sda{1..4}
% ls /tmp/media/
sda1  sda2  sda3  sda4
% zsh -c 'echo /tmp/media/sda[1234]'
/tmp/media/sda1 /tmp/media/sda2 /tmp/media/sda3 /tmp/media/sda4
% bash -c 'echo /tmp/media/sda[1234]'
/tmp/media/sda1 /tmp/media/sda2 /tmp/media/sda3 /tmp/media/sda4
% ksh -c 'echo /tmp/media/sda[1234]'
/tmp/media/sda1 /tmp/media/sda2 /tmp/media/sda3 /tmp/media/sda4
% busybox ash -c 'echo /tmp/media/sda[1234]'
/tmp/media/sda1 /tmp/media/sda2 /tmp/media/sda3 /tmp/media/sda4
% dash -c 'echo /tmp/media/sda[1234]'
/tmp/media/sda1 /tmp/media/sda2 /tmp/media/sda3 /tmp/media/sda4
% rc -c 'echo /tmp/media/sda[1234]'
/tmp/media/sda1 /tmp/media/sda2 /tmp/media/sda3 /tmp/media/sda4


cortman 08-14-2012 09:20 PM

Quote:

Originally Posted by ntubski (Post 4754271)
Why is the head useless? If 2 or more of the directories exist you need to select only a single one, no?

That's exactly why I included it; so that the variable wouldn't be "sda1 \n sda2 \n sda3" or something to that effect...
I make no pretenses at being proficient in scripting; I just like the challenge, and a little experimentation! :) I was hoping someone could help show better ways to do it.

David the H. 08-15-2012 03:57 AM

Notice that there's a difference between brace expansion and pattern-matching globbing anyway.

Brace expansion generates every possible combination first, then runs the given operation using that list. This means you'll get "file not found" errors on every combo that doesn't exist, assuming you use it in that fashion. But it is very handy for generating lists of similar text strings, particularly in loops, with printf, or in commands like mkdir.

Pattern matching, OTOH, simply searches for any existing files that fit the pattern and returns them as a list. Only if nothing is found at all do you possibly get an error, as it will then return the literal globbing string (the exact behavior may be configurable with shell settings). globbing is also used to test arbitrary text strings in case statements and the expanded [[..]] test facility in bash/ksh.


eval is occasionally used with brace expansion because of the shell parsing order. Since the shell processes brace expansions before doing parameter expansions, a pattern like {$a..$b} will not work without it.

I would not generally recommend this, however, due to eval's security issues. Unless you can guarantee in your code that the variables will always be clean, you should use other techniques instead, such as seq.


Finally, a note on the results of unSpawn's brace expansion test. His first one shows "sh" as expanding them normally, but it actually depends entirely on which shell your system has been set up with to process /bin/sh. Since brace expansion is simply undefined by posix, not counter to it, it's left up to the shell doing the executing to decide how to handle such code. unSpawn's system obviously has /bin/sh linked to a shell that understands brace expansion, probably bash. Most POSIX shells will simply treat them as literal text strings, as the rest of his tests demonstrate.

Note also that csh and tcsh are not bourne-based shells, and not posix-compliant, so it's no surprise that they give different results. Their scripting syntax has many differences compared to the common Linux shells (and their behavior is less predictable).


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