如何从串中“序列化”和“反序列化”命令行参数?

时间:2010-06-18 11:22:16

标签: perl bash serialization command-line

我打电话给我的剧本:

$ ./script 'a!#*`*&
^$' "sdf sdf\"qw sdsdf" 1 -- 2 3

它得到了论据:

1: a!#*`*&
^$
2: sdf sdf"qw sdsdf
3: 1
4: --
5: 2
6: 3

如果我需要在本地调用具有相同参数的内容,我会这样做:

someprogram "$@"

但是如何将所有数组放入字符串(存储在文件或环境变量中或通过TCP传递)然后将其转回到某处的命令行参数?我希望它简单,简洁,安全。

export CMDLINE="$@"
# What is in CMDLINE now? Escaped or not?

sh -c "someprogram $CMDLINE"
# Will it do what I mean?

理想情况下,我需要两个程序:第一个转弯将命令行参数转换为[a-zA-Z0-9_]*字符串,另一个转回我可以使用的命令行参数。

更新:编写了两个版本的脚本对。哪个更有用?

2 个答案:

答案 0 :(得分:1)

创建了两个脚本:一个将其参数序列化为[a-ZA-Z0-9=_]*字符串http://vi-server.org/vi/bin/serialize.sh,其他脚本启动此命令行(带有可选的前置参数)http://vi-server.org/vi/bin/deserialize.sh

序列化:

#!/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"

反序列化:

#!/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[@]}"

示例:

deserialize `serialize qqq www` echo

答案 1 :(得分:0)

在其他答案中与Bash脚本不兼容

将命令行参数序列化为[a-zA-Z0-9=_]*字符串的脚本:http://vi-server.org/vi/bin/serialize

#!/usr/bin/perl
use MIME::Base64;
map {print encode_base64($_,'')."_" } @ARGV;

将其反序列化的脚本(可选择在其他参数前加上):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);

还有类似的环境脚本:http://vi-server.org/vi/bin/envserialize http://vi-server.org/vi/bin/envdeserialize