Convert varible to number for dd command using Shell script - linux

I parsed /proc/PID/maps using shell script , now I have 2 variable
START_ADDR=982fe000
END_ADDR=984fe000
I want to use those variable for dd using shell script command like:
dd if=SOME_MEMORY skip=START_ADDR count=(END_ADDR-START_ADDR) of=out.bin bs=1
How can I convert those variable for dd?

As you didn't mention which shell you are using, I am assuming you are using bash.
Keeping that in mind, you can modify your above command as shown below to make it work.
dd if=$SOME_MEMORY skip=$START_ADDR count=$((0x$END_ADDR - 0x$START_ADDR)) of=out.bin bs=1
You need to make sure the variables SOME_MEMORY, END_ADDR and START_ADDR are accessible and present in current shell environment, to verify you can do
echo $SOME_MEMORY, echo $START_ADDR and similarly echo $END_ADDR

Related

Why is the command in /proc/XXX/cmdline truncated but not the arguments

I have a small bash script
#!/bin/bash
echo $(cat /proc/$PPID/cmdline | strings -1)
I call this script from a perl script which is run through nginx.
my $output_string = `/tmp/my_bash_script.sh`;
print $output_string;
When I load this in a browser, the result is something like:
/mnt/my_working_d -d /etc/my_httpd -f /etc/my_httpd/conf/httpd.conf
The location of the perl script is indeed somewhere in /mnt/my_working_directory/.... but why is this truncated and is there anyting I can do to log the whole command. I don't think the cmdline limit of 4k characters (?) which seems hardcoded in the kernel applies here.

Using "read" to set variables

In bash from the CLI I can do:
$ ERR_TYPE=$"OVERLOAD"
$ echo $ERR_TYPE
OVERLOAD
$ read ${ERR_TYPE}_ERROR
1234
$ echo $OVERLOAD_ERROR
1234
This works great to set my variable name dynamically; in a script it doesn't work. I tried:
#!/bin/env bash
ERR_TYPE=("${ERR_TYPE[#]}" "OVERLOAD" "PANIC" "FATAL")
for i in "${ERR_TYPE[#]}"
do
sh -c $(echo ${i}_ERROR=$"1234")
done
echo $OVERLOAD_ERROR # output is blank
# I also tried these:
# ${i}_ERROR=$(echo ${i}_ERROR=$"1234") # command not found
# read ${i}_ERROR=$(echo ${i}_ERROR=$"1234") # it never terminates
How would I set a variable as I do from CLI, but in a script? thanks
When you use dynamic variables names instead of associative arrays, you really need to question your approach.
err_type=("OVERLOAD" "PANIC" "FATAL")
declare -A error
for type in "${err_type[#]}"; do
error[$type]=1234
done
Nevertheless, in bash you'd use declare:
declare "${i}_error=1234"
Your approach fails because you spawn a new shell, passing the command OVERLOAD_ERROR=1234, and then the shell exits. Your current shell is not affected at all.
Get out of the habit of using ALLCAPSVARNAMES. One day you'll write PATH=... and then wonder why your script is broken.
If the variable will hold a number, you can use let.
#!/bin/bash
ERR_TYPE=("OVERLOAD" "PANIC" "FATAL")
j=0
for i in "${ERR_TYPE[#]}"
do
let ${i}_ERROR=1000+j++
done
echo $OVERLOAD_ERROR
echo $PANIC_ERROR
echo $FATAL_ERROR
This outputs:
1000
1001
1002
I'd use eval.
I think this would be considered bad practice though (it had some thing to do with the fact that eval is "evil" because it allows bad input or something):
eval "${i}_ERROR=1234"

Unix: What does cat by itself do?

I saw the line data=$(cat) in a bash script (just declaring an empty variable) and am mystified as to what that could possibly do.
I read the man pages, but it doesn't have an example or explanation of this. Does this capture stdin or something? Any documentation on this?
EDIT: Specifically how the heck does doing data=$(cat) allow for it to run this hook script?
#!/bin/bash
# Runs all executable pre-commit-* hooks and exits after,
# if any of them was not successful.
#
# Based on
# http://osdir.com/ml/git/2009-01/msg00308.html
data=$(cat)
exitcodes=()
hookname=`basename $0`
# Run each hook, passing through STDIN and storing the exit code.
# We don't want to bail at the first failure, as the user might
# then bypass the hooks without knowing about additional issues.
for hook in $GIT_DIR/hooks/$hookname-*; do
test -x "$hook" || continue
echo "$data" | "$hook"
exitcodes+=($?)
done
https://github.com/henrik/dotfiles/blob/master/git_template/hooks/pre-commit
cat will catenate its input to its output.
In the context of the variable capture you posted, the effect is to assign the statement's (or containing script's) standard input to the variable.
The command substitution $(command) will return the command's output; the assignment will assign the substituted string to the variable; and in the absence of a file name argument, cat will read and print standard input.
The Git hook script you found this in captures the commit data from standard input so that it can be repeatedly piped to each hook script separately. You only get one copy of standard input, so if you need it multiple times, you need to capture it somehow. (I would use a temporary file, and quote all file name variables properly; but keeping the data in a variable is certainly okay, especially if you only expect fairly small amounts of input.)
Doing:
t#t:~# temp=$(cat)
hello how
are you?
t#t:~# echo $temp
hello how are you?
(A single Controld on the line by itself following "are you?" terminates the input.)
As manual says
cat - concatenate files and print on the standard output
Also
cat Copy standard input to standard output.
here, cat will concatenate your STDIN into a single string and assign it to variable temp.
Say your bash script script.sh is:
#!/bin/bash
data=$(cat)
Then, the following commands will store the string STR in the variable data:
echo STR | bash script.sh
bash script.sh < <(echo STR)
bash script.sh <<< STR

Parsing a variable in shell scripting

I am new to shell scripting just started off.
I have written this script
#!/bin/sh
profile_type= cat /www/data/profile.conf
echo $profile_type
the o/p of this script is
. /tmp/S_panicA1.txt
. /tmp/S_panicA0.txt
away_Def="panicA1 panicA0"
away_Byp=0
away_Sts=$((panicA1+panicA0-away_Byp))
In this i want to get panicA1 panicA0 and 0 and store it in other variable how to do this?
When you want to assign the output of a command to a variable, you use the dollar parenthesis syntax.
foo=$(cat /my/file)
You can also use the backticks syntax.
foo=`cat /my/file`
In your script, you simply run the command cat and assign its result, nothing, to your variable. Hence the output consisting of the content of your file, result of cat, followed by an empty line, result of echo with an empty variable.

Initiating dynamic variables (variable variables) in bash shell script

I am using PHP CLI through bash shell. Please check Manipulating an array (printed by php-cli) in shell script for details.
In the following shell code I am able to echo the key- value pairs that I get from the PHP script.
IFS=":"
# parse php script output by read command
php $PWD'/test.php' | while read -r key val; do
echo $key":"$val
done
Following is the output for this -
BASE_PATH:/path/to/project/root
db_host:localhost
db_name:database
db_user:root
db_pass:root
Now I just want to initiate dynamic variables inside the while loop so that I can use them like $BASE_PATH having value '/path/to/project/root', $db_host having 'localhost'
I come from a PHP background. I would like something like $$key = $val of PHP
Using eval introduces security risks that must be considered. It's safer to use declare:
# parse php script output by read command
while IFS=: read -r key val; do
echo $key":"$val
declare $key=$val
done < <(php $PWD'/test.php')
If you are using Bash 4, you can use associative arrays:
declare -A some_array
# parse php script output by read command
while IFS=: read -r key val; do
echo $key":"$val
some_array[$key]=$val
done < <(php $PWD'/test.php')
Using process substition <() and redirecting it into the done of the while loop prevents the creation of a subshell. Setting IFS for only the read command eliminates the need to save and restore its value.
You may try using the eval construct in BASH:
key="BASE_PATH"
value="/path/to/project/root"
# Assign $value to variable named "BASE_PATH"
eval ${key}="${value}"
# Now you have the variable named BASE_PATH you want
# This will get you output "/path/to/project/root"
echo $BASE_PATH
Then, just use it in your loop.
EDIT: this read loop creates a sub-shell which will not allow you to use them outside of the loop. You may restructure the read loop so that the sub-shell is not created:
# get the PHP output to a variable
php_output=`php test.php`
# parse the variable in a loop without creating a sub-shell
IFS=":"
while read -r key val; do
eval ${key}="${val}"
done <<< "$php_output"
echo $BASE_PATH

Resources