Skip to content

Commit c575a44

Browse files
authored
Fix backtick evaluation in add-script and run-script inline scripts (#263)
1 parent 90228ca commit c575a44

File tree

9 files changed

+63
-5
lines changed

9 files changed

+63
-5
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
| Feature | Description | Install method | Version |
1212
| ------- | ----------- | -------------- | ------- |
13-
| [add-script](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/add-script) | Add a script from a URL or inline text to /usr/local/bin during devcontainer build | custom | 1.0.0 |
13+
| [add-script](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/add-script) | Add a script from a URL or inline text to /usr/local/bin during devcontainer build | custom | 1.1.0 |
1414
| [alexpasmantier/television](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/alexpasmantier-television) | `tv` — fuzzy finder for files, text, and more | gh release | 1.0.1 |
1515
| [ankitpokhrel/jira-cli](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/ankitpokhrel-jira-cli) | `jira` — feature-rich interactive Jira command line client | gh release | 1.0.0 |
1616
| [apt-build-essential](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/apt-build-essential) | `gcc`/`g++`/`make` — C/C++ compiler toolchain via the build-essential package | apt | 1.0.0 |
@@ -78,7 +78,7 @@
7878
| [rclone](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/rclone.org) | `rclone` — sync files to/from cloud storage | gh release | 1.0.1 |
7979
| [restic.net](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/restic.net) | `restic` — fast, encrypted, deduplicated backups | gh release | 1.0.1 |
8080
| [ripgrep](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/ripgrep) | `rg` — fast grep alternative (ripgrep) | gh release | 1.0.1 |
81-
| [run-script](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/run-script) | Run a script from a URL or inline text during devcontainer build | custom | 1.0.0 |
81+
| [run-script](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/run-script) | Run a script from a URL or inline text during devcontainer build | custom | 1.1.0 |
8282
| [schpet/linear-cli](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/schpet-linear-cli) | `linear` — CLI to access linear.com issue tracker | gh release | 1.0.2 |
8383
| [smallstep.com](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/smallstep.com) | `step` — zero-trust security toolkit and CA | gh release | 1.0.2 |
8484
| [socket.dev/sfw-free](https://github.com/devcontainer-community/devcontainer-features/tree/main/src/socket.dev-sfw-free) | `sfw` — network security proxy that blocks malicious dependencies | gh release | 1.0.0 |

src/add-script/devcontainer-feature.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "add-script",
33
"id": "add-script",
4-
"version": "1.0.0",
4+
"version": "1.1.0",
55
"description": "Add a script from a URL or inline text to /usr/local/bin during devcontainer build",
66
"documentationURL": "https://github.com/devcontainer-community/devcontainer-features/tree/main/src/add-script",
77
"options": {

src/add-script/install.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ echo_banner() {
3131
}
3232

3333
install() {
34+
# Re-read SCRIPT from the env file verbatim to prevent shell evaluation of
35+
# backticks: the devcontainer CLI wraps option values in double quotes in the
36+
# env file and then sources it, which causes bash to evaluate backticks.
37+
# Reading the file directly with awk avoids this evaluation.
38+
if [ -f ./devcontainer-features.env ]; then
39+
SCRIPT=$(awk '/^SCRIPT="/{sub(/^SCRIPT="/,"");v=$0;f=1;next}f{v=v"\n"$0}END{if(f){sub(/"$/,"",v);printf"%s",v}}' ./devcontainer-features.env)
40+
fi
41+
3442
if [ -z "${NAME}" ]; then
3543
echo "No script name provided. Nothing to do."
3644
return 0

src/run-script/devcontainer-feature.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "run-script",
33
"id": "run-script",
4-
"version": "1.0.0",
4+
"version": "1.1.0",
55
"description": "Run a script from a URL or inline text during devcontainer build",
66
"documentationURL": "https://github.com/devcontainer-community/devcontainer-features/tree/main/src/run-script",
77
"options": {

src/run-script/install.sh

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ echo_banner() {
3131
}
3232

3333
install() {
34+
# Re-read SCRIPT from the env file verbatim to prevent shell evaluation of
35+
# backticks: the devcontainer CLI wraps option values in double quotes in the
36+
# env file and then sources it, which causes bash to evaluate backticks.
37+
# Reading the file directly with awk avoids this evaluation.
38+
if [ -f ./devcontainer-features.env ]; then
39+
SCRIPT=$(awk '/^SCRIPT="/{sub(/^SCRIPT="/,"");v=$0;f=1;next}f{v=v"\n"$0}END{if(f){sub(/"$/,"",v);printf"%s",v}}' ./devcontainer-features.env)
40+
fi
41+
3442
if [ -n "${URL}" ] && [ -n "${SCRIPT}" ]; then
3543
printf >&2 '=== [ERROR] Both "url" and "script" options are provided. Please provide only one.\n'
3644
exit 1
@@ -41,7 +49,6 @@ install() {
4149
return 0
4250
fi
4351

44-
local tmpScript
4552
tmpScript="$(mktemp)"
4653
trap 'rm -f "${tmpScript}"' EXIT
4754

test/add-script/scenarios.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"test-backtick": {
3+
"image": "debian:latest",
4+
"features": {
5+
"add-script": {
6+
"name": "test-backtick",
7+
"script": "#!/bin/bash\necho `hostname`"
8+
}
9+
}
10+
}
11+
}

test/add-script/test-backtick.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
source dev-container-features-test-lib
6+
7+
check "test-backtick script exists" test -f /usr/local/bin/test-backtick
8+
check "test-backtick script is executable" test -x /usr/local/bin/test-backtick
9+
check "test-backtick script contains verbatim backtick" grep -qF '`hostname`' /usr/local/bin/test-backtick
10+
11+
reportResults

test/run-script/scenarios.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"test-backtick": {
3+
"image": "debian:latest",
4+
"features": {
5+
"run-script": {
6+
"script": "echo backtick_test=`hostname` > /tmp/devcontainer-run-script-test.txt"
7+
}
8+
}
9+
}
10+
}

test/run-script/test-backtick.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
source dev-container-features-test-lib
6+
7+
check "run-script created output file" test -f /tmp/devcontainer-run-script-test.txt
8+
check "run-script output contains expected prefix" grep -q 'backtick_test=' /tmp/devcontainer-run-script-test.txt
9+
check "run-script output contains non-empty value" grep -qv 'backtick_test=$' /tmp/devcontainer-run-script-test.txt
10+
11+
reportResults

0 commit comments

Comments
 (0)