How to "serialize" and "deserialize" command line arguments to/from string?
I call my script:
$ ./script 'a!#*`*&
^$' "sdf sdf\"qw sdsdf" 1 -- 2 3
It gets arguments:
1: a!#*`*&
^$
2: sdf sdf"qw sdsdf
3: 1
4: --
5: 2
6: 3
If I need to call something with the same arguments locally, I do this:
someprogram "$@"
But how can I put all that array to a string (to store in file or in environment variable or pass over TCP eaisly) and then turn it back to command line arguments somewhere? I want it to be simple, short and secure.
export CMDLINE="$@"
# What is in CMDLINE now? Escaped or not?
sh -c "someprogram $CMDLINE"
# Will it do what I mean?
Ideally I want two programs: the first turns turns command line paramerets into a [a-zA-Z0-9_]*
string, the other turns it back to command-line parameters I can use.
Update: written 2 versions of pairs of scripts. 开发者_运维技巧Which is more useful?
Created two scripts: one serializes it's arguments to a [a-ZA-Z0-9=_]*
strings http://vi-server.org/vi/bin/serialize.sh, other starts this command line (with optional prepended arguments) http://vi-server.org/vi/bin/deserialize.sh.
Serialize:
#!/bin/bash
n=$#;
for ((i=0; i<$n; ++i)); do
if [ -z "$1" ]; then
echo 1
else
printf '%s' "$1" | base64 -w 0
echo
fi
shift
done | tr '\n' '_'
echo -n "0"
Deserialize:
#!/bin/bash
if [ -z "$1" ]; then
echo "Usage: deserialize data [optional arguments]"
echo "Example: \"deserialize cXFx_d3d3_0 eee rrr\""
echo " will execute \"eee rrr qqq www\""
exit 1;
fi
DATA="$1"; shift
i=0
for A in ${DATA//_/' '}; do
if [ "$A" == "0" ]; then
break;
fi
if [ "$A" == "1" ]; then
A=""
fi
ARR[i++]=`base64 -d <<< "$A"`
done
exec "$@" "${ARR[@]}"
Example:
deserialize `serialize qqq www` echo
Incompatible with Bash script in the other answer
Script to serialize command-line arguments to [a-zA-Z0-9=_]*
string: http://vi-server.org/vi/bin/serialize
#!/usr/bin/perl
use MIME::Base64;
map {print encode_base64($_,'')."_" } @ARGV;
Script to deserialize it back (optionally prepending other arguments): http://vi-server.org/vi/bin/deserialize
#!/usr/bin/perl
use MIME::Base64;
if($#ARGV<0) {
print << "EOF";
Usage: deserialize data [optional prepended arguments]
Example: deserialize \$(serialize 3 4 " 5 " "" "'6'" '`8`') echo 1 2
EOF
exit
}
my @A = map {decode_base64($_)} split '_', shift @ARGV;
exec (@ARGV,@A);
Also there are similar scripts for environment: http://vi-server.org/vi/bin/envserialize http://vi-server.org/vi/bin/envdeserialize
精彩评论