How do I make an entire directory executable?

Another good option is Incron. It works on inotify with specifiable conditions for a given location.

So I can say watch this folder, when you see a file created, run a command.

Just as a sample incrontab...

/path/to/scripts IN_CREATE chmod +x $@$#  # <--- this arcane bit is path ($@) + file ($#)

One could similarly use the path/file as arguments to a bash script to allow it to filter by .py extensions if needed.


chmod +x /path/to/python/scripts/dir/*.py 

Will make executable all current .py files in directory /path/to/python/scripts/dir.

I'm not aware of an auto-tool as you describe. It might be possible to have a macro in your editor that could do this, but not with the editor I use. ;-)


As a first step, you could try this in your ~/.vimrc:

autocmd BufWritePost *.py silent execute "! chmod +x %"
  • This runs chmod +x on the filename for all .py files when you write to them. Looking at the list of events (:h events), I can't find an event where a new file is created, so I had to settle for running each time it is written to.
  • The first time the chmod is applied, the file gets changed, and vim will alert you to that:

    "test.py" [New] 0L, 0C written
    W16: Warning: Mode of file "test.py" has changed since editing started
    See ":help W16" for more info.
    [O]K, (L)oad File:
    

    I tried a couple of tricks to make it autoread just for this change, but no luck. So you'll have to press Enter twice.


When initiated, the script below automatically changes the permissions of all files of a given type (extension) in a directory (one time). After that, the script checks the directory every 5 seconds for newly added files, and changes the permissions if the file is of the given type (in this case a .py file)

It has a few options: in this case, it makes the newly added files executable, but other actions are possible too, as defined in the line: command = "chmod +x". Additionally, you can define (change) on what kind of files (language extensions) the action should be performed.

How to use

Copy the script below into an empty file. Save it as change_permission.py and run it in the background by the command:

python3 <script> <folder_to_watch>

The script

#!/usr/bin/env python3

import subprocess
import time
import sys

directory = sys.argv[1]
command = "chmod +x"; check_interval = 5; extensions = (".py")

def current_files():
    read = subprocess.check_output(["ls", directory]).decode("utf-8").strip()
    return [item for item in read.split("\n") if item[item.rfind("."):] in extensions]

initial_files = current_files()
for file in initial_files:
    subprocess.call(["/bin/bash", "-c", command+" "+directory+"/"+file])

while True:
    update = current_files()
    for file in update:
        if not file in initial_files:
            subprocess.call(["/bin/bash", "-c", command+" "+directory+"/"+file])  
    initial_files = update
    time.sleep(check_interval)

*Note: if you need sudo privileges, simply run the script with sudo


Here is some info with a few commands that might help, check out http://ss64.com/bash/syntax-permissions.html

find . -type f -print0 | xargs -0 chmod 775 # change all file permissions in current directory

find . -type d -print0 | xargs -0 chmod 755 # change directory permissions

You could use the following header script. Place mkscript.sh in your $PATH. Execute mkscript.sh from the working directory where the python scripts are stored. The script creates some useful header info, titles the script and makes it executable, and then opens the chosen editor; in your case VIM.

I modified mkscript.sh, it will produce scripts with the python extension *.py

The variable ${PYTHON_VERSION} is called, so PYTHON_VERSION="/usr/bin/python --version" has been added to the /etc/environment file. Have a look at https://help.ubuntu.com/community/EnvironmentVariables

#!/bin/bash -       
#title           :mkscript.sh
#description     :This script will make a header for a PYTHON script.
#author      :bgw
#date            :20111101
#version         :0.4    
#usage       :bash mkscript.sh
#notes           :Install Vim and Emacs to use this script.
#bash_version    :4.1.5(1)-release
#==============================================================================

today=$(date +%Y%m%d)
div=======================================

/usr/bin/clear

_select_title(){

    # Get the user input.
    printf "Enter a title: " ; read -r title

    # Remove the spaces from the title if necessary.
    title=${title// /_}

    # Convert uppercase to lowercase.
    title=${title,,}

    # Add .sh to the end of the title if it is not there already.
    [ "${title: -3}" != '.py' ] && title=${title}.py

    # Check to see if the file exists already.
    if [ -e $title ] ; then 
        printf "\n%s\n%s\n\n" "The script \"$title\" already exists." \
        "Please select another title."
        _select_title
    fi

}

_select_title

printf "Enter a description: " ; read -r dscrpt
printf "Enter your name: " ; read -r name
printf "Enter the version number: " ; read -r vnum

# Format the output and write it to a file.
printf "%-16s\n\
%-16s%-8s\n\
%-16s%-8s\n\
%-16s%-8s\n\
%-16s%-8s\n\
%-16s%-8s\n\
%-16s%-8s\n\
%-16s%-8s\n\
%-16s%-8s\n\
%s\n\n\n" '#!/usr/bin/python -' '#title' ":$title" '#description' \
":${dscrpt}" '#author' ":$name" '#date' ":$today" '#version' \
":$vnum" '#usage' ":./$title" '#notes' ':' '#python_version' \
":${PYTHON_VERSION}" \#$div${div} > $title

# Make the file executable.
chmod +x $title

/usr/bin/clear

_select_editor(){

    # Select between Vim or Emacs.
    printf "%s\n%s\n%s\n\n" "Select an editor." "1 for Vim." "2 for Emacs."
    read -r editor

    # Open the file with the cursor on the twelth line.
    case $editor in
        1) vim +12 $title
            ;;
        2) emacs +12 $title &
            ;;
        *) /usr/bin/clear
           printf "%s\n%s\n\n" "I did not understand your selection." \
               "Press <Ctrl-c> to quit."
           _select_editor
            ;;
    esac

}

_select_editor