Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I'm having a very weird error when trying to make a script callable. I have a scripts directory in /srv/projectname/scripts where I store you know scripts to be called as cron jobs for different projects. I'm trying at add a new one and seeing very weird behavior. In debugging I reproduce it using this set of commands

from /srv/projectname/scripts create a file create a file

vi helloworld.sh

insert text exactly:

#!/usr/bin/env bash

echo "Hello World!"

Make the script executable and try to call it:

chmod +x helloworld.sh
./helloworld.sh

Which gives:

-bash: ./helloworld.sh: Permission denied

Make sure there isn't a code error:

bash helloworld.sh

Which gives:

Hello World!

Copy the script to home and call it:

cp helloworld.sh ~/helloword.sh
~/helloword.sh

Which gives:

Hello World!

I have no idea what is going on. I have tried a lot of variants where I give the full path, same error, or if I sudo which gives no error, but also doesn't print "Hello World!".

Other details: Running on: Ubuntu 12.04.4 LTS I have also noticed that I can't tab-complete to the full name of a script that gives me this error, but I can once I have moved it. The directory /srv/projectname is a git repo but this script hasn't been added to it yet, I because I usually only do that once its working yet.

ls -l lines for the script and scripts directory are

-rwxrwxr-x 1 ubuntu ubuntu     41 Apr 21 20:25 helloworld.sh
drwxrwxr-x 3 ubuntu ubuntu 4096 Apr 21 20:25 scripts

respectively

Any help would be awesome.

EDIT: Gilles had the answer. To save anyone else who has this problem a google search.

sudo mount /srv/projectname/ -o remount

reloads the edited fstab, and everything works again.

share|improve this question
1  
Post the output of ls -l /srv/projectname/scripts to your question. –  i08in Apr 21 at 20:54
    
Do you want the full ls -l or just the line for the script? -rwxrwxr-x 1 ubuntu ubuntu 41 Apr 21 20:25 helloworld.sh –  TristanMatthews Apr 21 at 20:57
    
Just for the file would be file, but then post the permissions for the folder too. –  i08in Apr 21 at 20:57
    
Is /srv (or /srv/projectname) a mountpoint for a separate filesystem? if so what is its fs type and mount options? –  steeldriver Apr 21 at 21:11
1  
and the mount options? are you sure it's not mounted noexec? –  steeldriver Apr 21 at 22:40

1 Answer 1

up vote 3 down vote accepted

The file permissions say that it is executable, yet the file is not executable. There are three reasons why this can happen.

  • You didn't dig deep enough into the file permissions — there is an access control list that makes the file non-executable to you. You can see a file's ACL with the command getfacl /path/to/file. This is not the case here since ls -l shows that there is no ACL on the file (there would be a + at the end of the permissions, e.g. -rwxr-xr-x+).
  • The file is stored on a volume that is mounted with the noexec option. This option is implied by having users in an fstab line (if you want to make a filesystem user-mountable and to allow users to execute files on it, use noauto,users,exec). This mount option causes all regular files to be non-executable regardless of their permissions.
  • The file is a script that references an interpreter that isn't executable in its shebang line, or a dynamically-linked binary that references a dynamic loader that isn't executable. This isn't the case here given that copying the file results in a file that you can execute (and /usr/bin/env is executable anyway).

By a process of elimination, the file is on a volume mounted with the noexec option.

The only workarounds are:

  • Don't mount the volume with the noexec option. This option has no security implications (unlike nosuid and nodev, which do). It is mostly useful for filesystems with no notion of execute permissions, where you get to choose between making everything executable or nothing.
  • Copy the file before executing it.
  • Use a bind mount or bindfs to create a view of the filesystem where executable files are executable.
  • Invoke the interpreter or dynamic loader explicitly, e.g. here bash helloworld.sh. This doesn't execute helloworld.sh, it excecutes /bin/bash which reads from helloworld.sh.
share|improve this answer
    
To add to this answer, I would guess that the the file is on a ntfs disk. There is currently no way to run or write on ntfs file systems without "hacky" external programs –  Atsch Apr 21 at 23:10
    
@Atsch Uh? You can write on NTFS with ntfs-3g, and executing isn't a problem. –  Gilles Apr 21 at 23:20
    
Thanks Gilles, It was the noexec problem. My AWS instance had rebooted for the first time and I had set up fstab wrong. All of my cron jobs are actually called with "python script_name", which seems to run just fine, so I hadn't noticed. –  TristanMatthews Apr 22 at 2:48
    
@gilles afaik ntfs-3g is a workaround, and even if not there's a reason for not including it in most distros –  Atsch Apr 22 at 10:03
    
@Atsch I don't know what you think ntfs-3g is a workaround for, nor why it would matter. What is this “most distros” that you speak of? It doesn't include Ubuntu, Debian, Arch, Gentoo, Fedora, nor RHEL/CentOS if you include EPEL. You can write to NTFS on Linux, this has been the case for years. (And you can run, too — this is no more difficult than reading.) –  Gilles Apr 22 at 10:17

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.