create a short cut in mac terminal - python

I'm trying to create a short cut for a mac terminal such that when I write 'jj' the following line of code used in terminal will run:
python 5_7_16.py
My partner can write the program for Linux but he's not able to do it for Mac. He managed to write the path of the code as follows
FPTH="/Users/kylefoley/PycharmProjects/inference_engine2/inference2/Proofs/5_7_16.py"
When I'm using the pycharm software these are the first two lines of code I use before I can use python 5_7_16.py
cd inference2
cd Proofs
We already have the python file 'jj' saved in the right location and we can almost get it to work but not quite.
Also, software has three modes: output to excel, output to django, output to mysql. For reasons that I don't understand my partner thought we needed to write down in our file what type of mode is active. I don't understand why this is the case because all that information is already stored in the 5_7_16 file. Just in case it helps, here are the first lines of the python code.
excel = True
mysql = False
if not excel and not mysql:
from inference2.models import Define3, Archives, Input
from inference2 import views
if mysql:
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
print BASE_DIR
sys.path.append(BASE_DIR)
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "inference_engine2.settings")
import django
django.setup()
from inference2 import views
from inference2.models import Define3, Archives, Input
So here is what he wrote so far, thought again, I don't understand why all this is necessary. I would think that all you would need would be to just tell the mac terminal what code you want to run:
FPTH="/Users/kylefoley/PycharmProjects/inference_engine2/inference2/Proofs/5_7_16.py"
vmysql=$(sed -i ‘’ -E ’s/^mysql = \(.*\)/\1/g’ $FPTH)
vexcel=$(sed —i ‘’ E ’s/^excel = \(.*\)/\1/g’ $FPTH)
echo $vexcel
echo $vmysql
if [ "$vexcel" == "True" ] ; then
echo "Excel"
elif [ "$vmysql" = "True" ]
then
echo "Mysql"
else
echo "Django"
fi
if [ "$vexcel" = "True" ] ; then
echo "Excel is set”
python $FPTH
elif [ "$vmysql" = "True" ]
then
echo "Mysql is set”
python $FPTH
else
echo “Django is set”
cd /dUsers/kylefoley/PycharmProjects/inference_engine2
python manage.py runserver
fi

You need to add the alias in your .bash_profile file.
For details, check: About .bash_profile, .bashrc, and where should alias be written in?
Below are the steps to follow:
# Step 1: Go To home directory
cd
# Step 2: Edit ".bash_profile" file OR, create if not exists
vi .bash_profile
# In this file add entry at last as:
# alias jj="python ~/inference2/Proofs/5_7_16.py"
# ^ OR whatever is the path to file
# Now, close the file
# Step 3: Refresh bash shell environment
source ~/.bash_profile
You are good to do jj now.
From the bash manpage:
When bash is invoked as an
interactive login shell, or as a
non-interactive shell with the
--login option, it first reads and executes commands from the file
/etc/profile, if that file exists.
After reading that file, it looks for
~/.bash_profile, ~/.bash_login, and
~/.profile, in that order, and reads
and executes commands from the first
one that exists and is readable. The
--noprofile option may be used when the shell is started to inhibit this
behavior.

Related

Ignoring a specific file in a shell script for loop

My shell script loops through a given directory to execute a python script. I want to be able to ignore a specific file which is export_config.yaml. This is currently used in the for loop and prints out error on the terminal I want it to totally ignore this file.
yamldir=$1
for yaml in ${yamldir}/*.yaml; do
if [ "$yaml" != "export_config.yaml" ]; then
echo "Running export for $yaml file...";
python jsonvalid.py -p ${yamldir}/export_config.yaml -e $yaml -d ${endDate}
wait
fi
done
Your string comparison in the if statement is not matching export_config.yaml because for each iteration of your for loop you are assigning the entire relative file path (ie "$yamldir/export_config.yaml", not just "export_config.yaml") to $yaml.
First Option: Changing your if statement to reflect that should correct your issue:
if [ "$yaml" != "${yamldir}/export_config.yaml" ]; then
#etc...
Another option: Use basename to grab only the terminal path string (ie the filename).
for yaml in ${yamldir}/*.yaml; do
yaml=$(basename $yaml)
if [ "$yaml" != "export_config.yaml" ]; then
#etc...
Third option: You can do away with the if statement entirely by doing your for loop like this instead:
for yaml in $(ls ${yamldir}/*.yaml | grep -v "export_config.yaml"); do
By piping the output of ls to grep -v, you can exclude any line including export_config.yaml from the directory listing in the first place.

Chain of UNIX commands within Python

I'd like to execute the following UNIX command in Python:
cd 2017-02-10; pwd; echo missing > 123.txt
The date directory DATE = 2017-02-10 and OUT = 123.txt are already variables in Python so I have tried variations of
call("cd", DATE, "; pwd; echo missing > ", OUT)
using the subprocess.call function, but I’m struggling to find documentation for multiple UNIX commands at once, which are normally separated by ; or piping with >
Doing the commands on separate lines in Python doesn’t work either because it “forgets” what was executed on the previous line and essentiality resets.
You can pass a shell script as a single argument, with strings to be substituted as out-of-band arguments, as follows:
date='2017-02-10'
out='123.txt'
subprocess.call(
['cd "$1"; pwd; echo missing >"$2"', # shell script to run
'_', # $0 for that script
date, # $1 for that script
out, # $2 for that script
], shell=True)
This is much more secure than substituting your date and out values into a string which is evaluated by the shell as code, because these values are treated as literals: A date of $(rm -rf ~) will not in fact try to delete your home directory. :)
Doing the commands on separate lines in Python doesn’t work either
because it “forgets” what was executed on the previous line and
essentiality resets.
This is because if you have separate calls to subprocess.call it will run each command in its own shell, and the cd call has no effect on the later shells.
One way around that would be to change the directory in the Python script itself before doing the rest. Whether or not this is a good idea depends on what the rest of the script does. Do you really need to change directory? Why not just write "missing" to 2017-02-10/123.txt from Python directly? Why do you need the pwd call?
Assuming you're looping through a list of directories and want to output the full path of each and also create files with "missing" in them, you could perhaps do this instead:
import os
base = "/path/to/parent"
for DATE, OUT in [["2017-02-10", "123.txt"], ["2017-02-11", "456.txt"]]:
date_dir = os.path.join(base, DATE)
print(date_dir)
out_path = os.path.join(date_dir, OUT)
out = open(out_path, "w")
out.write("missing\n")
out.flush()
out.close()
The above could use some error handling in case you don't have permission to write to the file or the directory doesn't exist, but your shell commands don't have any error handling either.
>>> date = "2017-02-10"
>>> command = "cd " + date + "; pwd; echo missing > 123.txt"
>>> import os
>>> os.system(command)

Calling a python to run a shell script

I'm currently trying run the shell script by using the os.system method in python.
Python code:
file = open("History.txt","w")
file.write(history)
os.system('./TFPupload.sh')
Shell script code:
#!/bin/sh
HOST="ftp.finalyearproject95.com"
USER='*****'
PASSWD='*****'
FILE='History.txt'
ftp -n $HOST <<END_SCRIPT
quote USER $USER
quote PASS $PASSWD
put $FILE
quit
END_SCRIPT
echo ">>>uploaded<<<\n"
exit 0
At first, when i tried to run the python code and shell script one by one it works perfectly. However, when i attempt to use python to run shell script, instead of uploading the 'History.txt' file that contains data into the database, the file uploaded is an empty file. When i check using 'nano History.txt', it does contain data, only when it passes the text file to the database will be empty. Why is it?
Use With statement to open files whenever possible .
with open("History.txt","w") as file :
file.write(history)
os.system('./TFPupload.sh')
with statement takes care of closing the fd on its own .
some Ref : What is the python "with" statement designed for?

bash program with argument from terminal

I am trying to write a bash script to a run a python program which take a files name and print values in the terminal.My bash program should take three argument from the terminal.First the python program name,second the folder name and third the file name where I want to store the output of my python program.
#!/bin/bash
directoryname = "$1"
programname = "$2"
newfilename ="$3"
for file in directoryname
do
python3 programname "$file" >> newfilename
done
and I am executing the program as follows:
./myscript.sh mypython.py /home/data myfile.txt
but it is giving error as :
./myscript.sh: line 2: directoryname: command not found
./myscript.sh: line 3: programname: command not found
./myscript.sh: line 4: newfilename: command not found
Please help me with this.I am pretty new to bash script.
Change to:
#!/bin/bash
directoryname="$1"
programname="$2"
newfilename="$3"
for file in $directoryname
do
python3 "$programname" "$file" >> "$newfilename"
done
No spaces around the =. A var is tagged with the $ before its name. In general, a var expansion is better if quoted ($var vs "$var").
And, I assume that you do want the list of files inside a directory, but the directoryname is only the directory itself (as /home/user/). If so, you will need:
for file in "$directoryname"/*
The unnecessary spaces in-between = and the variable names and the values are causing the issues, remove the spaces and try again. Will work. :)
#!/bin/bash
directoryname="$1"
programname="$2"
newfilename="$3"
for file in directoryname
do
python3 programname "$file" >> newfilename
done

Rewrite config file based on standard error output

I'm new to Linux and have a Fedora 20 build for a class. We installed Tripwire using the default, out of the box configs and I want to take the standard errors from the install to fix the config file.
To collect the errors:
tripwire -m i -c tw.cfg 2> errors
To clean the error file up for processing:
cat errors.txt | grep "/" | cut -d " " -f 3 > fixederrors
This gives me a nice clean file with one path per line i.e.:
/bin/ash
/bin/ash.static
/root/.Xresources
I would like to automate this process by comparing the data in fixederrors to the config file and prepend matching strings with a '#'.
I tried sed, but it commented out the whole config file!
sed 's/^/#/g' fixederrors > commentederrors
Alternatively, I thought about comparing the config file and the fixederrors and creating a third file. Is there a way to take two files, compare them, and remove duplicated data?
Any help is appreciated. I tried bash and python, but I don't know enough and went down the rabbit hole on this one. Again, this is for my growth and not in a production environment.
Let's we suppose that you have this input file named fixederrors "clean"
/bin/ash
/bin/ash.static
/root/.Xresources
this input as configuration file named config.original
use /bin/ash
use /bin/bash
do stuff with /bin/ash.static and friends
/root/.Xresources
do other stuff...
With this script in bash
#!/bin/bash
Input_Conf_File="config.original" # Original configuration file
Output_Conf_File="config.new" # New configuration file
Input_Error_File="fixederrors" # File of cleaned error
rm -f $Output_Conf_File # Let's we create a new file erasing old
while read -r line ; do # meanwhile there are line in config file
AddingChar="" # No Char to add #
while IFS= read -r line2 ; do # For each line of Error file,
# here you can add specific rules for your match e.g
# line2=${line2}" " # if it has always a space after...
[[ $line == *$line2* ]] && AddingChar="#" # If found --> Change prefix "#"
done < $Input_Error_File
echo "${AddingChar}${line}" >> $Output_Conf_File # Print in new file
done < $Input_Conf_File
cat $Output_Conf_File # You can avoid this it's only to check results
exit 0
You will have this output
#use /bin/ash
use /bin/bash
#do stuff with /bin/ash.static and friends
#/root/.Xresources
do other stuff...
Note:
IFS= removes trailing spaces in read
Use wisely because e.g. the match /bin/ash will catch lines with /bin/ash.EVERYTHING; so if it exists a line in your configuration input file as /bin/ash.dynamic will be commented too. Without prior knowledge of your configuration file it's not possible to set a specific rule, but you can do it starting from here.

Categories