AC Voltage
AC Voltage

Reputation: 349

I get syntax error when i call script from c++ program

I'm trying to write a program that will allow easier management of Arduino projects. So I wrote bash script that creates all the necessary folders and files for me and when I execute it I runs like champ. Because I want to change directory in the working terminal inside the script I run script like this

. ./initialize.sh

This is also working great, but because I am writing C++ program, sourcing this script from program is giving me headache.

So inside a program I run this script like this:

system(". /usr/lib/avrduino/script/initialize.sh");

and then when I run the program I get this error:

sh: 25: /usr/lib/avrduino/script/initialize.sh: Syntax error: "(" unexpected (expecting "}")

Running the script from the program like this:

system("/usr/lib/avrduino/script/initialize.sh");

works without error but it runs in subshell.

Syntax error points to this line in script

options=("uno" "mega" "mega2560" "atmega8" "atmega168" "atmega328" "pro" "pro5v" "pro328" "pro5v328")

How come that when I run this script outside of the program it's working like champ, but run this script from program and you have a problem ?

EDIT: Script code

   #!/bin/bash

BLACK='\033[0;30m'
RED='\033[0;31m'
GREEN='\033[0;32m'
BROWN='\033[0;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
LGRAY='\033[0;37m'
DGRAY='\033[1;30m'
LRED='\033[1;31m'
LGREEN='\033[1;32m'
YELLOW='\033[1;33m'
LBLUE='\033[1;34m'
LPURPLE='\033[1;35m'
LCYAN='\033[1;36m'
WHITE='\033[1;37m'
NC='\033[0m'

makefile()
{
  BOARD="default"
  PS3='Chose your board: '
  options=("uno" "mega" "mega2560" "atmega8" "atmega168" "atmega328" "pro" "pro5v" "pro328" "pro5v328")
  select opt in "${options[@]}"
  do case $opt in 
    "uno") BOARD="uno"
    cp -r /usr/lib/avrduino/data/boards_info/uno/board-info.h .
    MCU="atmega328P"
    F_CPU="16000000UL"
    ;;
  "mega") BOARD="mega" 
    cp -r /usr/lib/avrduino/data/boards_info/mega/board-info.h .
    F_CPU="16000000UL"
    ;;
  "mega2560") BOARD="mega2560"
    cp -r /usr/lib/avrduino/data/boards_info/mega2560/board-info.h .
    F_CPU="16000000UL"
    ;;
  "atmega8") BOARD="atmega8"
    cp -r /usr/lib/avrduino/data/boards_info/atmega8/board_-nfo.h .
    MCU="atmega8"
    F_CPU="16000000UL"
    ;;
  "atmega168") BOARD="atmega168"
    cp -r /usr/lib/avrduino/data/boards_info/atmega168/board-info.h .
    MCU="atmega168"
    F_CPU="16000000UL"
    ;;
  "atmega328") BOARD="atmega328"
    cp -r /usr/lib/avrduino/data/boards_info/atmega328/board-info.h .
    MCU="atmega328P"
    F_CPU="16000000UL"
    ;;
  "pro") BOARD="pro"
    cp -r /usr/lib/avrduino/data/boards_info/pro/board-info.h .
    MCU="unknow"
    F_CPU="16000000UL"
    ;;
  "pro5v") BOARD="pro5v"
    cp -r /usr/lib/avrduino/data/boards_info/pro5v/board-info.h .
    MCU="unknown"
    F_CPU="16000000UL"
    ;;

  "pro328") BOARD="pro328"
    cp -r /usr/lib/avrduino/data/boards_info/pro328/board-info.h .
    MCU="atmega328P"
    F_CPU="16000000UL"
    ;;
  "pro5v328") BOARD= "pro5v328"
    cp -r /usr/lib/avrduino/data/boards_info/pro5v328/board-info.h .
    MCU="atmega328P"
    F_CPU="16000000UL"
    ;;
  *)
    echo "Error : Input is not valid"
    echo "Exiting..."
    return 1 
    ;;
    esac
    break
  done
  [ -e Makefile ] && rm Makefile
  read -p "Do you want to configure your Makefile settings [Y/n]: " CONFIGURE
  if { [ "$CONFIGURE" == "Y" ] || [ "$CONFIGURE" == "y" ]; }; then
    read -p "Enter your MCU: " MCU
    read -p "Enter F_CPU: " F_CPU
  fi
  read -p "Enter ARDUINO_PORT: " ARDUINO_PORT
  echo "ARDUINO_DIR = /usr/share/arduino">>Makefile
  echo "BOARD_TAG = $BOARD">>Makefile
  echo "ARDUINO_PORT = $ARDUINO_PORT">>Makefile
  echo "NO_CORE = 1">>Makefile
  echo "AVRDUDE_ARD_PROGRAMMER = arduino">>Makefile
  echo "HEX_MAXIMUM_SIZE = 30720">>Makefile
  echo "AVRDUDE_ARD_BAUDRATE = 115200">>Makefile
  echo "#ISP_LOW_FUSE = 0xFF">>Makefile
  echo "#ISP_HIGH_FUSE = 0xDA">>Makefile
  echo "#ISP_EXT_FUSE = 0x05">>Makefile
  echo "#ISP_LOCK_FUSE_PRE = 0x3F">>Makefile
  echo "#ISP_LOCK_FUSE_POST = 0x0F">>Makefile
  echo "MCU = $MCU">>Makefile
  echo "F_CPU = $F_CPU">>Makefile
  echo "VARIANT = standard">>Makefile
  echo "ARDUINO_LIBS =">>Makefile
  echo "include /usr/share/arduino/Arduino.mk">>Makefile
  echo "$BOARD|$MCU|" >> .avrduino.txt

  clear
  echo -e "${LGREEN}Makefile settings${NC}"
  echo -e "${LBLUE}ARDUINO_DIR = ${LRED}/usr/share/arduino ${NC}"
  echo -e "${LBLUE}BOARD_TAG = ${LRED}$BOARD${NC}"
  echo -e "${LBLUE}ARDUINO_PORT = ${LRED}$ARDUINO_PORT${NC}"
  echo -e "${LBLUE}NO_CORE = ${LRED}1${NC}"
  echo -e "${LBLUE}AVRDUDE_ARD_PROGRAMMER = ${LRED}arduino${NC}"
  echo -e "${LBLUE}HEX_MAXIMUM_SIZE = ${LRED}30720${NC}"
  echo -e "${LBLUE}AVRDUDE_ARD_BAUDRATE = ${LRED}115200${NC}"
  echo -e "${DGRAY}#ISP_LOW_FUSE = ${RED}0xFF${NC}"
  echo -e "${DGRAY}#ISP_HIGH_FUSE = ${RED}0xDA${NC}"
  echo -e "${DGRAY}#ISP_EXT_FUSE = ${RED}0x05${NC}"
  echo -e "${DGRAY}#ISP_LOCK_FUSE_PRE = ${RED}0x3F${NC}"
  echo -e "${DGRAY}#ISP_LOCK_FUSE_POST = ${RED}0x0F${NC}"
  echo -e "${LBLUE}MCU = ${LRED}$MCU${NC}"
  echo -e "${LBLUE}F_CPU = ${LRED}$F_CPU${NC}"
  echo -e "${LBLUE}VARIANT = ${LRED}standard${NC}"
  echo -e "${LBLUE}ARDUINO_LIBS =${NC}"

}

initializeProject()
{
  read -p "Project name: " PROJECT_NAME
  if [ ! -e PROJECT_NAME ]; then
    mkdir $PROJECT_NAME
    cd $PROJECT_NAME
    makefile #Call function that makes makefile
    cp -r /usr/lib/avrduino/data/include/ .
    echo -e "${LGREEN}Project created successfully ${NC}"
  else 
    echo "AVRduino: Project with name [ $PROJECT_NAME ] already exists. "
    echo "AVRduino: Stop project wizard and exit."
  fi
}

clear
initializeProject

Upvotes: 0

Views: 431

Answers (2)

molbdnilo
molbdnilo

Reputation: 66371

. doesn't execute the script as a process, it only loads it into your current shell process.

In that context, your "shebang" line, #!/bin/bash, is just a comment.
(You can put #! doodle poodle noodle there and it will run just as well.)

When you use system, it executes in /bin/sh, and thus your bash script has syntax errors.

One way to execute scripts is to make them executable:

chmod +x /usr/lib/avrduino/script/initialize.sh

and then you can just pass it directly to system:

system("/usr/lib/avrduino/script/initialize.sh");

Or, you could explictly execute it in bash:

system("/bin/bash /usr/lib/avrduino/script/initialize.sh");

OK, here's a way one might solve your "changing directory" problem:

Rewrite initialize.sh so it takes the project name as an argument instead of asking for it interactively (that's how normal Unix tools work, so stick with it).

Then add the following to your .bashrc:

make_project()
{
    /usr/lib/avrduino/script/initialize.sh "$1" && cd "$1"
}

Then you can say make_project foo and get transported to the directory "foo".

Upvotes: 2

pakistanprogrammerclub
pakistanprogrammerclub

Reputation: 827

Most likely it is the misplaced shebang causing a default shell to be run - make sure the shebang is at the beginning of the first line

#!/bin/bash
# rest of script

If that does not work change your system call to

system("/bin/bash /usr/lib/avrduino/script/initialize.sh");

Upvotes: 1

Related Questions