Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,20 @@ noexec --version

### Help

Display usage information (run without arguments):
Display usage information (run without arguments or with -h/--help):

```bash
noexec
```

```bash
noexec -h
```

```bash
noexec --help
```

### Credits

Show author and project information:
Expand Down
44 changes: 37 additions & 7 deletions docs/install.sh
Original file line number Diff line number Diff line change
@@ -1,13 +1,43 @@
curl "https://raw.githubusercontent.com/ByteJoseph/noexec/refs/heads/main/src/noexec" -o noexec
set -e

# Check for required commands
for cmd in curl dirname command cp chmod rm; do
if ! command -v "$cmd" >/dev/null 2>&1; then
echo "Error: Required command '$cmd' not found. Please install it and try again."
exit 1
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Consider using curl’s failure flags (e.g., -fS) instead of fully suppressing output with -s.

-s hides curl’s error output, which makes debugging failures harder. A pattern like curl -fSLo noexec "…" keeps normal output quiet while still failing on HTTP errors and showing a clear error message on stderr.

fi
done

echo "Downloading noexec..."
if ! curl -s "https://raw.githubusercontent.com/ByteJoseph/noexec/refs/heads/main/src/noexec" -o noexec; then
echo "Error: Failed to download noexec."
exit 1
fi

file="noexec"
dir_name=$(dirname "$(command -v bash)")
bash_path=$(command -v bash)
if [ -z "$bash_path" ]; then
echo "Error: Could not find bash in PATH."
rm -f "$file"
exit 1
fi

dir_name=$(dirname "$bash_path")

if [ ! -w "$dir_name" ]; then
echo "Error: No write permission to $dir_name. Please run with appropriate permissions."
rm -f "$file"
exit 1
fi

if [ -f "$file" ]; then

cp "$file" "$dir_name/$file"
chmod +x "$dir_name/$file"
echo "noexec Installed Successfully"
rm "noexec"
echo "noexec Installed Successfully to $dir_name/$file"
rm "$file"
echo ""
echo "Start using now"
noexec
echo "Start using now by typing: noexec"
Comment on lines 33 to +39
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Use mv instead of cp followed by rm to reduce operations and potential failure modes.

Because the file is only needed in its final location, you can replace the cp + rm pair with mv "$file" "$dir_name/$file". This simplifies the logic, avoids having two copies briefly, and removes the risk of a leftover file if rm fails.

Suggested change
if [ -f "$file" ]; then
cp "$file" "$dir_name/$file"
chmod +x "$dir_name/$file"
echo "noexec Installed Successfully"
rm "noexec"
echo "noexec Installed Successfully to $dir_name/$file"
rm "$file"
echo ""
echo "Start using now"
noexec
echo "Start using now by typing: noexec"
if [ -f "$file" ]; then
mv "$file" "$dir_name/$file"
chmod +x "$dir_name/$file"
echo "noexec Installed Successfully to $dir_name/$file"
echo ""
echo "Start using now by typing: noexec"

else
echo "Error: Downloaded file not found."
exit 1
fi
73 changes: 48 additions & 25 deletions src/noexec
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#!/bin/bash

version=1.0
version=1.1
exe="$1"
if [ -z "$exe" ]; then
cat <<EOF

case "$exe" in
"" | "-h" | "--help")
cat <<EOF
╭────────────────────────────────────────────╮
│ Usage : noexec <executable> <args...> │
│ │
Expand All @@ -13,43 +15,64 @@ if [ -z "$exe" ]; then
│ Options: │
│ -v, --version Display the version and │
│ exit. │
│ -h, --help Display this help and │
│ exit. │
│ --credits Display author and │
│ project information. │
╰────────────────────────────────────────────╯
EOF
exit 0
fi
if [ "--credits" = "$exe" ]; then
cat <<EOF
exit 0
;;
"--credits")
cat <<EOF
╭───────────────────────────────────────────────────╮
│ noexec v$version │
│ Author : Joseph Joseph (ByteJoseph) │
│ GitHub : https://github.com/ByteJoseph/noexec │
│ Email : bytejoseph23[at]gmail.com │
╰───────────────────────────────────────────────────╯
EOF
exit 0
fi
if [ "--version" = "$exe" ] || [ "-v" = "$exe" ]; then
echo " V $version"
exit 0
fi
exit 0
;;
"-v" | "--version")
echo "noexec version $version"
exit 0
;;
esac
target=$(command -v bash)
if [ -z "$target" ]; then
echo "Error: Could not determine system PATH from bash location." >&2
exit 1
fi
strip_target=$(dirname "$target")

if [ ! -w "$strip_target" ]; then
echo "Error: No write permission to $strip_target" >&2
exit 1
fi

if [ -f "$exe" ]; then
year=$(date +%Y)
base="$(basename "$exe")"
temp_exec="$strip_target/${base}${year}"

cp "$exe" "$temp_exec"
chmod +x "$temp_exec"
trap 'rm -f "$temp_exec"' EXIT
"$temp_exec" "${@:2}"
exit_code=$?
rm -f "$temp_exec"
exit $exit_code
base="$(basename "$exe")"
temp_exec=$(mktemp -p "$strip_target" "${base}.XXXXXXXX") || {
echo "Error: Failed to create temporary file in $strip_target" >&2
exit 1
}
trap 'rm -f "$temp_exec"' EXIT

cp "$exe" "$temp_exec" || {
echo "Error: Failed to copy $exe to $temp_exec" >&2
exit 1
}

chmod +x "$temp_exec"
"$temp_exec" "${@:2}"
exit_code=$?
exit $exit_code
elif [ -d "$exe" ]; then
echo "Error: '$exe' is a directory, not a file." >&2
exit 1
else
echo "File $exe doesn't exist"
echo "Error: File '$exe' doesn't exist." >&2
exit 1
fi

Expand Down
50 changes: 50 additions & 0 deletions tests/test_noexec.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/bin/bash

# Setup a fake bin directory and add it to PATH
FAKE_BIN="$(pwd)/fake_bin_test"
mkdir -p "$FAKE_BIN"
cp "$(command -v bash)" "$FAKE_BIN/bash"
export PATH="$FAKE_BIN:$PATH"

NOEXEC="$(pwd)/src/noexec"

# Helper for testing
assert_contains() {
local output="$1"
local expected="$2"
local name="$3"
if echo "$output" | grep -q "$expected"; then
echo "PASS: $name"
else
echo "FAIL: $name"
echo " Expected to contain: $expected"
echo " Actual output: $output"
exit 1
fi
}

# Test Case 1: Verify successful execution of a simple script passing arguments
echo 'echo "Test Output: $1 $2"' > test_script.sh
chmod +x test_script.sh
OUTPUT=$(bash "$NOEXEC" ./test_script.sh "Arg1" "Arg2")
assert_contains "$OUTPUT" "Test Output: Arg1 Arg2" "Successful execution with arguments"

# Test Case 2: Verify correct output for the --help flag
OUTPUT=$(bash "$NOEXEC" --help)
assert_contains "$OUTPUT" "Usage : noexec" "Help flag output"

# Test Case 3: Verify error message when the input file does not exist
OUTPUT=$(bash "$NOEXEC" non_existent_file 2>&1)
assert_contains "$OUTPUT" "Error: File 'non_existent_file' doesn't exist." "Missing file error"

# Test Case 4: Verify error message when the input is a directory instead of a file
mkdir -p test_dir
OUTPUT=$(bash "$NOEXEC" test_dir 2>&1)
assert_contains "$OUTPUT" "Error: 'test_dir' is a directory, not a file." "Directory input error"

# Cleanup
rm test_script.sh
rm -rf test_dir
rm -rf "$FAKE_BIN"

echo "All tests passed!"