Bash "Pass Through" -Skript für Android-Build, Space-Problem

606
codeScriber

Ich habe ein Android-Build, das ich anpassen muss, die Frage ist ehre und nicht im stackoverflow, da mein Problem mit bash ist. Ich habe ein Skript geschrieben:

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

Das Skript nimmt an, die Parameter, die es erhalten hat, zu übernehmen, den Parameter --custom-package com.some.package hinzuzufügen und den Rest der Parameter beizubehalten. Der erste ($ 1) -Parameter ist die Aktion, also muss ich ihn zuerst behalten.

Das Problem liegt beispielsweise bei Leerzeichen in den Verzeichnisnamen './my android dir /'. wenn ich den Parameter einfach weitergebe: param = "$ param $ 1"; Scheisse; Wenn ich Leerzeichen im Namen habe, funktioniert es nicht, weil der neue Parameter nicht mit Escapezeichen versehen ist (mit "). Wenn ich den Code oben verwende, funktioniert er trotzdem nicht, weil bash aus irgendeinem Grund das Zeichen" char "ignoriert und immer noch das Leerzeichen berücksichtigt in der Mitte als separater Parameter! Hier ist die Ausgabe des Laufs: './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 

Wie Sie am Ende beim Drucken des Echo-Bash sehen können, betrachten Sie die Zeichenfolge "/ Users / bankleumi / some dir" als zwei Zeichenfolgen, obwohl \ "IN die Zeichenfolge integriert sind. Wie kann ich Bash den Raum allein lassen?" (Ich habe versucht mit IFS zu spielen und es hat auch nicht funktioniert ...)

1

2 Antworten auf die Frage

2
grawity

Machen Sie sich nicht mit erneutem Zitieren aus, es funktioniert nicht, weil sh / bash die Wortaufteilung für Variablen verwendet. Das heißt, sie teilen den Wert auf, ohne zuvor die Anführungszeichen im Wert zu berücksichtigen.

Sie könnten das umgehen, indem Sie eval "$path/aapt-orig $params"...

Aber Bash hat Arrays, benutzt sie stattdessen:

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

Oder noch einfacher:

#!/usr/bin/env bash exec "$/aapt-orig" "$1" --custom-package com.leumi.leumiwallet "${@:2}" 
Randnotiz: `echo $ 0 | xargs dirname`? *Ja wirklich?* grawity vor 12 Jahren 2
Aus irgendeinem Grund, den ich sicher bin, dass @grawity besser versteht als ich, funktioniert die Verwendung von Anführungszeichen ebenfalls: `./aapt action" "/ Users / bankleumi / some dir /" "another_param" terdon vor 12 Jahren 0
@terdon: Ich bin mir nicht sicher, * wie * das funktionieren würde. Nachdem bash keine Anführungszeichen gegeben hat, ist "foo bar" "baz" genau dasselbe wie "foo bar baz" und aapt erhält es als drei Einzelwortargumente. grawity vor 12 Jahren 0
Keine Idee, @grawity, habe es nur aus einer Laune heraus versucht und es hat funktioniert. Ich habe das Skript im OP verwendet und das CLI-Argument wie oben gezeigt doppelt zitiert. Die relevante Ausgabe war: `+ Echoaktion --custom-package com.some.package / Users / bankleumi / some dir / another_param`. Bash-Version: `GNU-Bash, Version 4.2.36 (1) -release (x86_64-pc-linux-gnu)` terdon vor 12 Jahren 0
1
Rainer Blome

This should work with more shells, and may be easier to understand:

#!/bin/sh first="$1"; shift; exec "`dirname '$0'`/aapt-orig" "$first" --custom-package com.foo.bar "$@"; 

Note that it works because shells treat "$@" specially, see section "Special Parameters" in the Bash manpage.