Finalize project
This commit is contained in:
commit
c75cbff329
10
Makefile
Normal file
10
Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
PROGS = sh_quote
|
||||
CFLAGS = -std=c99 -pedantic
|
||||
|
||||
default: $(PROGS)
|
||||
|
||||
test: $(PROGS)
|
||||
./test_sh_quote
|
||||
|
||||
clean:
|
||||
rm -f $(PROGS)
|
39
README.md
Normal file
39
README.md
Normal file
@ -0,0 +1,39 @@
|
||||
# Shell quoting util
|
||||
|
||||
This tool was made to handle a specific edge case in shell scripting.
|
||||
|
||||
When you want to supply a command to some tool as a shell string, but you only have it as already expanded array.
|
||||
|
||||
This doesn't work as expected because `$@` is expanded, ending up as multiple arguments to `su`:
|
||||
|
||||
```
|
||||
su -c "$@"
|
||||
```
|
||||
|
||||
This does work as expected:
|
||||
|
||||
```
|
||||
su -c "$(sh_quote "$@")"
|
||||
```
|
||||
|
||||
Because all arguments must be relayed, `-h` or `--help` cannot be taken into account, so there is no helptext.
|
||||
|
||||
When no arguments are given, it returns without producing any output.
|
||||
|
||||
# Error messages
|
||||
|
||||
None. This program cannot fail.
|
||||
|
||||
If stdout is not writable, no sensible output will be generated.
|
||||
|
||||
If `$0` is not set, no output will be generated.
|
||||
|
||||
# Building
|
||||
|
||||
Run `make`.
|
||||
|
||||
# Testing
|
||||
|
||||
Run `make test`
|
||||
|
||||
The test script can also run on arbitrary programs: `./run_sh_quote /path/to/other_program`.
|
26
sh_quote.c
Normal file
26
sh_quote.c
Normal file
@ -0,0 +1,26 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
unsigned int i;
|
||||
char* p;
|
||||
char* delim = "'";
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (i > 1) putchar(' ');
|
||||
p = argv[i];
|
||||
|
||||
printf("%s", delim);
|
||||
while(*p != '\0') {
|
||||
if (p[0] == '\'') {
|
||||
printf("%s\\'%s", delim, delim);
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
if (p[0] == '\\') putchar('\\');
|
||||
putchar((p++)[0]);
|
||||
}
|
||||
printf("%s", delim);
|
||||
}
|
||||
putchar('\n');
|
||||
return 0;
|
||||
}
|
20
test_sh_quote
Executable file
20
test_sh_quote
Executable file
@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
PROG=${1:-./sh_quote}
|
||||
|
||||
run_test() {
|
||||
r=$($PROG "$2"|sed 's/^ *//;s/ *$//')
|
||||
if test "$r" == "$3"; then
|
||||
echo PASS "$1"
|
||||
else
|
||||
echo FAIL "$1"
|
||||
printf "Expected: %s\nGot: %s\n" "$3" "$r"
|
||||
fi
|
||||
}
|
||||
|
||||
run_test empty "" "''"
|
||||
run_test whitespace "Foo Bar" "'Foo Bar'"
|
||||
run_test quote "Foo'Bar" "'Foo'\''Bar'"
|
||||
run_test newline "Foo
|
||||
Bar" "'Foo
|
||||
Bar'"
|
||||
run_test trailing_space "Foobar " "'Foobar '"
|
Loading…
Reference in New Issue
Block a user