2

I'm trying to create a very simple python script that waits for a GPIO button press and then runs a shell script. I personally don't know much about python so what I've come up with is mostly from other sources with a similar issue.

import RPi.GPIO as GPIO
import time
import os

GPIO.setmode(GPIO.BCM)
GPIO.setup(16,GPIO.IN)

input = GPIO.input(16)

while True:
        inputValue = GPIO.input(16)
        if (inputValue == False):
                os.system("scan.sh")

So once the button on pin 16 is pressed, I need it to run the shell script "scan.sh". However when I run the python script it repeats

sh: 1: scan.sh: not found

and control+c won't end it. Nothing changes whether the button is pressed or not. What do I need to change?

1
  • 1
    Try providing the full path to scan.sh?
    – Brick
    Commented Dec 11, 2017 at 19:41

2 Answers 2

3

There are some points to look into / fix here:

  1. How is the button connected?

    • Does the button pull the pin to GND when pressed and does the pin have an external pull-up resistor to 3.3 V connected?
      Because with GPIO.input(16) == False you are checking if the pin is low. If there is no pull-up resistor connected the pin will float and this expression would be true more often than you want it to be (this might be the reason why your program tries to execute scan.sh without the button being pressed). You can setup the BCM chip's internal pull-up resistor in software with GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    • Is it really the BCM GPIO16 pin?
      With GPIO.setmode(GPIO.BCM) you are using the BCM chip's pin numbering. BCM GPIO16 maps to pin 36 on the 40-pin header.
  2. Run scan.shonly once when button is pressed.
    With checking GPIO.input(16) in the infinit loop you are polling the pin as fast as possible. So if the pin gets LOW, you are re-starting scan.sh really often until the pin gets HIGH. You could remember the last read state in a variable and execute scan.sh only if it was changed. But I would suggest to use the edge detection feature of the GPIO module. There are different options to do this. In the example below, an event is registered to detect a falling edge and execute a function if this happens.

  3. Let your Python script find scan.sh.
    As mentioned in the other aswer by joan, with os.system("scan.sh") the Python script executes a file in the current working directory. Depending on how you start the Python script, this is not the directory where your Python script resides. So the best would be to give an absolute path to scan.sh like os.system("/home/sam/myscripts/scan.sh")

  4. Make scan.sh executable.
    As also mentioned in the answer by joan, on linux you need to give permissions for a file to be executed. With chmod +x /home/sam/myscripts/scan.sh you will make your script executable.

So if your pin 36 (GPIO16) is connected to a button that pulls it to GND and your script is executable, than this should work:

import RPi.GPIO as GPIO
import os

# Define a callback function that will be called by the GPIO
# event system:
def onButton(channel):
    if channel == 16:
        os.system("/home/sam/myscripts/scan.sh")

# Setup GPIO16 as input with internal pull-up resistor to hold it HIGH
# until it is pulled down to GND by the connected button: 
GPIO.setmode(GPIO.BCM)
GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_UP)

# Register an edge detection event on FALLING edge. When this event
# fires, the callback onButton() will be executed. Because of
# bouncetime=20 all edges 20 ms after a first falling edge will be ignored: 
GPIO.add_event_detect(16, GPIO.FALLING, callback=onButton, bouncetime=20)

# The script would exit now but we want to wait for the event to occure
# so we block execution by waiting for keyboard input so every key will exit
# this script
input()
0

Re sh: 1: scan.sh: not found

Either:

  1. no file called scan.sh exists in the current working directory (of the script)
  2. scan.sh does not have the executable bit set
  3. the user has no permission to view scan.sh

I suppose 2. is the most likely.

To set the executable bit use the command chmod +x scan.sh

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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