LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Mobile
User Name
Password
Linux - Mobile This forum is for the discussion of all topics relating to Mobile Linux. This includes Android, Tizen, Sailfish OS, Replicant, Ubuntu Touch, webOS, and other similar projects and products.

Notices


Reply
  Search this Thread
Old 03-22-2012, 09:13 AM   #1
papa smurf151
LQ Newbie
 
Registered: Mar 2012
Posts: 3

Rep: Reputation: 0
Need help with a sed command within my script


Hello i have a problem. Let me give you a little background real quick. I have written a script that I run in script manager on my android phone. This script creates another script that goes into the init.d folder with in the /system/etc folder. Im trying to run a command in the main script thats run in the script manager that gives people the option to switch their i/o scheduler whenever they want to. Im using the sed command and its not working. Can someone please help me figure out the right command.

Here is the problem. Within the script manager script the script there are 7 different options. The main option runs the main part of the script which asks the user a few questions and saves each answer in different variables and injects those variables to the init.d script.

Code:
echo "$sched_1" > /sys/block/mmcblk0/queue/scheduler;
that works perfectly

the problem comes when within the script manager script im trying to give the option for someone to change the scheduler whenever they want rather than running the main part of the script again. the problem comes into play because there is 6 different possibilities that could be used for the $sched_1. Also I want to change another one of the lines that could have any answer for the variable cause its dealing with the process name of the launcher they are using.

ive tried this but its just not working

Code:
if [ "`grep "echo "Deadline" > /sys/block/mmcblk0/queue/scheduler" /system/etc/init.d/45smurfed`" ]; then 
	cat /system/etc/init.d/45smurfed \
	sed -i 's:echo "Deadline" > /sys/block/mmcblk0/queue/scheduler;:echo "Deadline" > /sys/block/mmcblk0/queue/scheduler;:g'
	>> /sdcard/45smurfed.tmp
	$sleep
	rm /system/etc/init.d/45smurfed
	$sleep
	cp -f /sdcard/45smurfed.tmp /system/etc/init.d/45smurfed
	$sleep
	rm /sdcard//45smurfed
	fi
thats just one case that it could be.

any help from the pros
 
Old 03-22-2012, 12:52 PM   #2
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Is this script a bash script, or a posix "sh" script, or what? It might also help to see an example of the text that's due to be modified, to let us test possible solutions.

Code:
cat /system/etc/init.d/45smurfed \
	sed -i...
The "\" at the end of the first line concatenates them into a single command. I believe you want to use a "|" pipe instead?


In any case this looks kinda ugly.

First of all $(..) is highly recommended over `..`, and if this is a bash script "[[" would be better than "[". (http://wiki.bash-hackers.org/syntax/...nal_expression)

I think the code would be cleaner to do all of your grepping first in one go, save the results into variables or an array, and test those. Even better would be if it's possible to use a case statement instead of ifs.

Also, I'm assuming $sleep is a variable containing a preset sleep command? That's not generally recommended. You should use functions to define regularly-used commands.
 
Old 03-22-2012, 01:08 PM   #3
papa smurf151
LQ Newbie
 
Registered: Mar 2012
Posts: 3

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by David the H. View Post
Is this script a bash script, or a posix "sh" script, or what? It might also help to see an example of the text that's due to be modified, to let us test possible solutions.

Code:
cat /system/etc/init.d/45smurfed \
	sed -i...
The "\" at the end of the first line concatenates them into a single command. I believe you want to use a "|" pipe instead?


In any case this looks kinda ugly.

First of all $(..) is highly recommended over `..`, and if this is a bash script "[[" would be better than "[". (http://wiki.bash-hackers.org/syntax/...nal_expression)

I think the code would be cleaner to do all of your grepping first in one go, save the results into variables or an array, and test those. Even better would be if it's possible to use a case statement instead of ifs.

Also, I'm assuming $sleep is a variable containing a preset sleep command? That's not generally recommended. You should use functions to define regularly-used commands.
im still really new at this and learning and self teaching with a little help from a friends of mine. id love it if you could look over my script and tell me what I can do to clean it up. This is a bash script i wrote to run in script manager that runs within android. It first gives 7 options. Option one runs the main script that edits the build.prop by searching a deleting certain lines than adding my own lines at the bottom of the build.prop. It then creates another script that goes into the /system/etc/init.d folder and adds in all types of tweaks from internet, 3g tweaks, governor tweaks, adj and minfree tweaks, I/O scheduler tweaks as well as some other tweaks. Here take a look at it so far. This is still my experimental build. The working build is working great but only has 4 different choices.
Attached Files
File Type: txt Smurfed_Out.sh.txt (88.0 KB, 10 views)

Last edited by papa smurf151; 03-22-2012 at 02:38 PM.
 
Old 03-23-2012, 12:46 PM   #4
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Whooh, that's a long script. I don't think I'm going to bother to read through it completely at this point.

But after a quick glance through it, I can give you some starting advice.

1)
As I asked before, do you need for this to be a portable, posix-based script? You called it a "bash" script, but #!/bin/sh means it runs in posix-compliant, lowest-common-denominator mode. If would certainly help things if you can specify the use of bash specifically (#!/bin/bash), and take advantage of its more powerful features.

And if so, what version of bash do you have available?


2)
It's considered bad practice to combine code and data in the same script, at least outside of trivial amounts. Most of your heredoc blocks would be better served if stored in separate files, and sourced or redirected as necessary. You could then make edits to the data files without worrying about corrupting the script itself, not to mention that it would also help improve readability.


3)
Speaking of which, a bit more effort on formatting would be helpful. A few more blank line breaks to separate sections and some clearer indentation would make things more readable and easily debuggable.

And comments! You really need to add some comments explaining the process of your script, i.e. what the code is supposed to be doing and how. It may seem perfectly clear to you now, but I guarantee you that a year or two down the line you're going to be wondering "just WTF is this bit here for?".


4)
You have at least one very long series of sed commands, which should probably also be set aside as a single separate external script to be called on when needed (using sed's -f option). Or at the very least use sed's -e option to specify multiple expressions in a single command.

The number of individual expressions could be greatly reduced too, with effective regex use. To pull out a single example (after removing the incorrect backslash terminators, as I demonstrated in my last post):

Code:
sed '/net.rmnet0.dns1/d' |
sed '/net.rmnet0.dns2/d' |
sed '/net.tiwlan0.dns1/d' |
sed '/net.tiwlan0.dns2/d' |

#revised:

sed -r -e '/net[.](rmnet|tiwlan)0[.]dns[12]/d' |
(Not to mention that, as written, it involves a Useless Use Of Cat. sed can read the filename directly.)


5)
FUNCTIONS! I see a lot of unnecessarily duplicated command lines that would be better handled through the use of a few functions. Write once, use many.


6)
Even outside of functions, there's an overwhelming number of areas where a few loops and variables would save you a huge amount of unnecessary duplication. I'd say most of the script, in fact. For example there's a series like this:

Code:
if [ "`cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq`" -eq 200000 ] && [ "`cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq`" -eq 1200000 ]; then
	echo "4" > /sys/devices/system/cpu/cpufreq/lulzactive/pump_up_step;

elif [ "`cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq`" -eq 200000 ] && [ "`cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq`" -eq 1400000 ]; then 
	echo "5" > /sys/devices/system/cpu/cpufreq/lulzactive/pump_up_step;

...etc...
You should do the "cat"-ing only ONCE, at the beginning, save the values into variables, and test those. (and if you use bash, you don't even need cat, as < behaves like cat when inside $() ).

Code:
scaling_min_freq=$( </sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq )
scaling_max_freq=$( </sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq )
pump_up_step="/sys/devices/system/cpu/cpufreq/lulzactive/pump_up_step"

if (( scaling_min_freq == 200000 && scaling_max_freq == 1200000 )); then
	echo "4" > "$pump_up_step"
elif (( scaling_min_freq == 200000 && scaling_max_freq == 1400000 )); then 
	echo "5" > "$pump_up_step"
...etc...

7)
As demonstrated in the above example, if you can use bash, the old [..] test brackets should ideally be replaced with [[..]] or ((..)) depending on if it's a string/file comparison or an integer evaluation.


8)
There are also areas that look like they could benefit from the use of arrays. Specifically there's one area where you have a series of variables, $PROCESS_1...$PROCESS_18, that could better be handled with an array and a few simple loops. Again, this would require the use of bash, as the posix specification doesn't include arrays.

Another example is this:

Code:
if [ -f "/system/build.prop.unsmurfed" ]; then
	rm /system/build.prop.unsmurfed;
fi
$sleep
if [ -f "/system/bin/build.prop.unsmurfed" ]; then
	rm /system/bin/build.prop.unsmurfed;
fi
$sleep

...etc...
But with an array:

Code:
smurfiles=(
	/system/build.prop.unsmurfed
	/system/bin/build.prop.unsmurfed
	/data/local.prop.unsmurfed
	...etc...
)

for file in "${smurfiles[@]}"; do
	[[ -f $file ]] && rm "$file"
	sleep
done


Anyway, that's enough for now. Try applying the suggestions I've made so far, and post back with the revised script. Then we can have another go at optimizing it. I'm sure that with just a bit of effort your script will be much cleaner, lighter, and faster.

Check out these links too for more advice:

http://mywiki.wooledge.org/BashGuide
http://mywiki.wooledge.org/BashFAQ
http://mywiki.wooledge.org/BashPitfalls

http://www.grymoire.com/Unix/Sed.html
http://www.grymoire.com/Unix/Regular.html

Last edited by David the H.; 03-23-2012 at 01:02 PM. Reason: small corrections
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Bash Script combination of sed with pwd command escaping slashes HaukeG Programming 2 10-06-2009 04:04 AM
Simple shell script - sed command Todd88 Programming 10 07-06-2008 04:33 PM
bash script to apply sed command only to a specific text area mauran Programming 6 07-13-2007 04:38 PM
bash script with grep and sed: sed getting filenames from grep odysseus.lost Programming 1 07-17-2006 11:36 AM
Command interpretation issue in Sed script file angel115 Programming 9 04-21-2006 07:26 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Mobile

All times are GMT -5. The time now is 03:42 PM.

Main Menu
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