我有一个需要自定义的 android 版本,问题出在 ehre 而不是 stackoverflow 上,因为我的问题与 bash 有关。我写了一个脚本:
#!/bin/bash -xv
params=$@
if [ "$#" -ge "2" ]; then
params=$1
shift
params="$params --custom-package com.some.package"
while [ "$#" -gt "0" ]; do
temp=$1
echo $1 | grep ' ' > /dev/null
if [ "$?" -eq "0" ]; then
temp=\"$1\"
fi
params="$params $temp"
shift
done
fi
path=$(echo $0|xargs dirname)
echo $params
$path/aapt-orig $params
该脚本假设采用它得到的参数,添加--custom-package com.some.package 参数并保留其余参数,第一个($1)参数是操作,所以我需要先保留它。
问题在于目录名称中的空格,例如 './my android dir/'。如果我只是传递参数:param ="$param $1"; shit; 如果名称中有空格,它不起作用,因为新参数没有转义(使用 "),如果我使用上面的代码,它仍然不起作用,因为出于某种原因 bash 忽略了 " 字符,仍然将中间的空格视为单独的参数!这是运行的输出:'./aapt action "/Users/bankleumi/some dir/" another_param'
'[' 0 -eq 0 ']'
+ temp='"/Users/bankleumi/some dir/"'
+ params='action --custom-package com.leumi.leumiwallet "/Users/bankleumi/some dir/"'
+ shift
+ '[' 1 -gt 0 ']'
+ temp=another_param
+ echo another_param
+ grep ' '
+ '[' 1 -eq 0 ']'
+ params='action --custom-package com.leumi.leumiwallet "/Users/bankleumi/some dir/" another_param'
+ shift
+ '[' 0 -gt 0 ']'
path=$(echo $0|xargs dirname)
echo $0|xargs dirname
++ echo ./aapt
++ xargs dirname
+ path=.
echo $params
+ echo action --custom-package com.leumi.leumiwallet '"/Users/bankleumi/some' 'dir/"' another_param
action --custom-package com.leumi.leumiwallet "/Users/bankleumi/some dir/" another_param
$path/aapt-orig $params
+ ./aapt-orig action --custom-package com.leumi.leumiwallet '"/Users/bankleumi/some' 'dir/"' another_param
正如您在最后打印 echo bash 时所看到的,即使字符串中集成了 \",它仍将字符串“/Users/bankleumi/some dir”视为两个字符串!我怎样才能让 bash 不改变空格?(我尝试使用 IFS,但也没有用……)
答案1
不要乱用重新引用,因为 sh/bash 对变量使用分词的方式,它不会起作用——也就是说,它们会分割值没有首先考虑值中的引号。
eval "$path/aapt-orig $params"
您可以使用...来解决这个问题。
但是 Bash 有数组,所以可以使用它们:
#!/usr/bin/env bash
args=()
args+=("$1"); shift
args+=(--custom-package com.leumi.leumiwallet)
for arg in "$@"; do
args+=("$arg")
done
exec "$(dirname "$0")/aapt-orig" "${args[@]}"
或者更简单:
#!/usr/bin/env bash
exec "${0%/*}/aapt-orig" "$1" --custom-package com.leumi.leumiwallet "${@:2}"
答案2
这应该适用于更多 shell,并且可能更容易理解:
#!/bin/sh
first="$1"; shift;
exec "`dirname '$0'`/aapt-orig" "$first" --custom-package com.foo.bar "$@";
请注意,它之所以有效是因为 shell 进行了"$@"
特殊处理,请参阅 Bash 手册页中的“特殊参数”部分。