Friday, November 20, 2015

Cron and Anacron to schedule jobs in Linux


ref https://tecadmin.net/crontab-in-linux-with-20-examples-of-cron-schedule/

$crontab -e   to edit
$crontab -l   to list
$crontab -l -u username   to list cron jobs of username


anacron

runs commands periodically. Unlike cron(8), it does not assume that the machine is running continuously. Hence, it can be used on machines that aren't running 24 hours a day, to control daily, weekly, and monthly jobs that are usually controlled by cron.
qyang@lubuntu-laptop:~$ service anacron start
qyang@lubuntu-laptop:~$ service anacron status
● anacron.service - Run anacron jobs
   Loaded: loaded (/lib/systemd/system/anacron.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2015-11-21 09:19:57 AEDT; 4s ago
 Main PID: 10233 (anacron)
   CGroup: /system.slice/anacron.service
           └─10233 /usr/sbin/anacron -dsq

Nov 21 09:19:57 lubuntu-laptop systemd[1]: Started Run anacron jobs.
Nov 21 09:19:57 lubuntu-laptop systemd[1]: Starting Run anacron jobs...
Nov 21 09:19:57 lubuntu-laptop anacron[10233]: Anacron 2.3 started on 2015-11-21
Nov 21 09:19:57 lubuntu-laptop anacron[10233]: Will run job `cron.daily' in 5 min.
Nov 21 09:19:57 lubuntu-laptop anacron[10233]: Will run job `svnsyncPQAFW.daily' in 15 min.
Nov 21 09:19:57 lubuntu-laptop anacron[10233]: Jobs will be executed sequentially

cron

Sample of downloading data regularly using cron Changing crontab
root@trac ~# cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user command
17 * * * * root    cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#25 6 * * * root test -x /usr/sbin/anacron || ( cd /root/AuctionResults && run-parts --report /root/AuctionResults)
00 12  * * 7 root test -x /usr/sbin/anacron || ( cd /root/AuctionResults && run-parts --report /root/AuctionResults)
#
Run any executable files,eg.runpython under nominated folder AuctionResults
root@trac ~# ls -al ~/AuctionResults
total 852
drwxr-xr-x  2 root root   4096 Nov 15 12:00 .
drwx------ 11 root root   4096 Sep  9 00:41 ..
-rwxr-xr-x  1 root root   1105 Jul 14 13:48 file-retrieve-via-url.py
-rwxr-xr-x  1 root root     39 Jun  9 22:43 runpython
qyang@lubuntu-laptop:~/Svn_Local_Personal/A_001_Notes$ locate cron |grep bin
/usr/bin/crontab
/usr/sbin/anacron
/usr/sbin/cron
/etc/cron.daily/.placeholder
/etc/cron.daily/0anacron
/etc/cron.daily/apport
/etc/cron.daily/apt
/etc/cron.daily/bsdmainutils
/etc/cron.daily/dpkg
/etc/cron.daily/logrotate
/etc/cron.daily/man-db
/etc/cron.daily/mlocate
/etc/cron.daily/ntp
/etc/cron.daily/passwd
/etc/cron.daily/popularity-contest
/etc/cron.daily/update-notifier-common
/etc/cron.hourly/.placeholder
/etc/cron.monthly/.placeholder
/etc/cron.monthly/0anacron
/etc/cron.weekly/.placeholder
/etc/cron.weekly/0anacron
/etc/cron.weekly/fstrim
/etc/cron.weekly/man-db
/etc/cron.weekly/update-notifier-common
/etc/default/anacron
/etc/default/cron
/etc/init/anacron.conf
/etc/init/cron.conf
/etc/init.d/anacron
/etc/init.d/cron

service control in debian/lubuntu/ubuntu - sysv-rc-conf


[1] wiki.debian.org

Install sysv-rc-conf via apt.
$sudo sysv-rc-conf


Aliasing Automatic Gain Control and FFT

Aliasing

A filter chosen in anticipation of a certain sample frequency is called an anti-aliasing filterAliasing on wiki. A real anti-aliasing filter trades off between bandwidth andaliasing
Undersampling, which causes aliasing.
Without an anti-aliasing filter, frequencies higher than the Nyquist frequency will influence the samples in a way that is misinterpreted by the interpolation process. Ref
  • Paper(pdf) from National Instruments on Aliasing and Sampling at Frequencies Above the Nyquist Frequency.
  • Notes:
    R (sampling rate) = 100MS/s
    fs (signal being sampled = 70MHz
    fN (the Nyquist frequency) = 50MHz
    fa (aliased frequency) = 30MHz
    The frequency of the aliased signal can be found from the following simple equation:
    fa = |R*n - fs|
    
    Although sampling at twice the Nyquist frequency will ensure that you measure the correct frequency of your signal, it will not be sufficient to capture the shape of the waveform. If the shape of the waveform is desired, you should sample at a rate approximately 10 times the Nyquist theory.
If known input frequency range, then sample rate more than 2*InputFreqRange? will remove aliasing. However, real input signal could include signal frequency higher than wanted frequency range, these high frequency signal will cause aliasing at pre-designed smapling rate. (high freq signal and low freq signal end up with same sampling points at lower (than required) sampling rate.) That's the whole reason u need anti-aliasing filter in the front end to filter out unsupported high frequency signals.

Automatic gain control - (AGC)

Finite Impulse Response (FIR) filter

FFT

Monday, November 16, 2015

Python: Retrieve files from URL link

file-retrieve-via-url.py
#!/usr/bin/env python
import urllib
from datetime import datetime

saveFileName = "Sydney-Auction-Result-"+datetime.now().strftime("%Y%m%d%H%M%S")+".pdf"
urllib.urlretrieve ("http://domainmastheads.homepriceguide.com.au/saturday_auction_results/Sydney.pdf",saveFileName )
saveFileName = "Adelaide-Auction-Result-"+datetime.now().strftime("%Y%m%d%H%M%S")+".pdf"
urllib.urlretrieve ("http://domainmastheads.homepriceguide.com.au/saturday_auction_results/Adelaide.pdf",saveFileName )
saveFileName = "Melbourne-Auction-Result-"+datetime.now().strftime("%Y%m%d%H%M%S")+".pdf"
urllib.urlretrieve ("http://domainmastheads.homepriceguide.com.au/saturday_auction_results/Melbourne.pdf",saveFileName )
saveFileName = "Brisbane-Auction-Result-"+datetime.now().strftime("%Y%m%d%H%M%S")+".pdf"
urllib.urlretrieve ("http://domainmastheads.homepriceguide.com.au/saturday_auction_results/Brisbane.pdf",saveFileName )
#saveFileName = "Sydney-Domain-Auction-Result-"+datetime.now().strftime("%Y%m%d%H%M%S")+".pdf"
#urllib.urlretrieve ("http://www.domain.com.au/apm/saturday_auction_results/Sydney_Domain.pdf",saveFileName )

Friday, November 13, 2015

Folders and files synchronisation using rsync in Linux


# Creat source folder and files and blank destination folder
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ mkdir src dst
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ mkdir src/a 
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ echo "hell a" > src/a/file1.txt
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ tree
.
├── dst
└── src
    └── a
        └── file1.txt

# rsync to test folder and file synch. Both 'a' and 'file1' appeared under 'dst'.
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ rsync --delete --checksum --recursive src/ dst/
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ tree
.
├── dst
│   └── a
│       └── file1.txt
└── src
    └── a
        └── file1.txt

# Test newly added folder 'b' being synched
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ mkdir src/b
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ rsync --delete --checksum --recursive src/ dst/
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ tree
.
├── dst
│   ├── a
│   │   └── file1.txt
│   └── b
└── src
    ├── a
    │   └── file1.txt
    └── b

# Test newly added file 'file2.txt' being synched
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ echo "hell b" > src/b/file2.txt
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ rsync --delete --checksum --recursive src/ dst/
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ tree
.
├── dst
│   ├── a
│   │   └── file1.txt
│   └── b
│       └── file2.txt
└── src
    ├── a
    │   └── file1.txt
    └── b
        └── file2.txt

# Test newly delete folder 'a' and 'file1.txt' inside being synched.
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ rm -rf src/a/
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ rsync --delete --checksum --recursive src/ dst/
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ tree
.
├── dst
│   └── b
│       └── file2.txt
└── src
    └── b
        └── file2.txt

# Test newly delete file 'file2.txt' being synched.
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ rm src/b/file2.txt 
rm: remove regular file ‘src/b/file2.txt’? y
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ rsync --delete --checksum --recursive src/ dst/
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ tree
.
├── dst
│   └── b
└── src
    └── b

# Add back 'file2.txt' and check
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ echo "hell b" > src/b/file2.txt
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ rsync --delete --checksum --recursive src/ dst/
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ tree
.
├── dst
│   └── b
│       └── file2.txt
└── src
    └── b
        └── file2.txt

# modify 'file2.txt' and check synch
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ cat dst/b/file2.txt
hell b
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ vi src/b/file2.txt
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ cat src/b/file2.txt
Modified ...hello b
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ rsync --delete --checksum --recursive src/ dst/
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ cat dst/b/file2.txt
Modified ...hello b
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ tree
.
├── dst
│   └── b
│       └── file2.txt
└── src
    └── b
        └── file2.txt


Using cp command line for multiple files copy
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ tree
.
├── dst
│   └── b
│       └── file2.txt
└── src
    ├── a
    │   └── file1.txt
    └── b
        ├── file2.txt
        └── file3.txt

5 directories, 4 files
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ cp {src/a/file1.txt,src/b/file{2..3}.txt} dst/
qyang@lubuntu-laptop:~/Trash/Sandbox-Trial$ tree
.
├── dst
│   ├── b
│   │   └── file2.txt
│   ├── file1.txt
│   ├── file2.txt
│   └── file3.txt
└── src
    ├── a
    │   └── file1.txt
    └── b
        ├── file2.txt
        └── file3.txt

Wednesday, November 11, 2015

Bash to synch one particular folder from one SVN repository to another SVN repository


#!/bin/bash

pushd ~/Svn_Local_Proj/Cascade/Firmware/ 

svn up
# Synch two local SVN copies,but ingore .svn etc.
rsync --delete --cvs-exclude --checksum --recursive ~/Svn_Local_Proj/Cascade/Firmware/ ~/Svn_Local_Proj_HomeTrac/Proj_FW/ 

pushd ~/Svn_Local_Proj_HomeTrac/Proj_FW/ 
svn up
#Add new files to repo if there are new files
svn add --force * --auto-props --parents --depth infinity
svn ci -m"Auto Synch SVN copy to Trac from Lubuntu"

popd
popd

Bash to copy files from AWS to local drive

#!/bin/bash

# Copy from AWS
# Password based ssh access, but downside is disclose plain text password. Better use ssh key pair based access
# sshpass -p "Password" scp -pv root@qqec2.tklapp.com:~/AuctionResults/*.pdf ./
rsync --checksum qqec2:~/AuctionResults/*.pdf ./
echo "Done synch with AWS"
ssh qqec2 "if [ ! -d 'AuctionResults-Bkup' ]; then mkdir -v AuctionResults-Bkup; echo 'Created folders that doesnot exist';fi;
#ssh qqec2 "if [ ! -d "AuctionResults-Bkup" ]; "
#"then mkdir -v AuctionResults-Bkup; "
#"echo "Created folders that doesnot exist";"
#"fi;"
#"cp -vp AuctionResults/*.pdf AuctionResults-Bkup/""
echo "Done moving all download pdf files to bkup folder on AWS"

Open a file browser from your current command prompt terminal directory


[1] www.howtogeek.com/open-a-file-browser-from-your-current-command-promptterminal-directory/


explorer .        # For windows command line
nautilus .        # Linux command line
open .            # MAC OS X
dolphin .         # Linux KDE 4

Saturday, November 7, 2015

Friday, November 6, 2015

DDD Front-End Debugger



Summary of DDD


The purpose of a debugger such as ddd is to allow you to see what is going on “inside” another
program while it executes—or what another program was doing at the moment it crashed.
ddd can do four main kinds of things (plus other things in support of these) to help you catch
bugs in the act:
• Start your program, specifying anything that might affect its behavior.
• Make your program stop on specified conditions.
• Examine what has happened, when your program has stopped.
• Change things in your program, so you can experiment with correcting the effects of one bug
and go on to learn about another.


Technically speaking, ddd is a front-end to a command-line debugger (called inferior debugger,
because it lies at the layer beneath ddd). ddd supports the following inferior debuggers:
• To debug executable binaries, you can use ddd with gdb, dbx, Ladebug, or xdb.
− gdb, the gnu debugger, is the recommended inferior debugger for ddd. gdb supports
native executables binaries originally written in C, C++, Java, Modula-2, Modula-3, Pascal, Chill, Ada, and FORTRAN. (see section “Using gdb with Different Languages” in
Debugging with gdb, for information on language support in gdb.)
− As an alternative to gdb, you can use ddd with the dbx debugger, as found on several
unix systems. Most dbx incarnations offer fewer features than gdb, and some of the
more advanced dbx features may not be supported by ddd. However, using dbx may be
useful if gdb does not understand or fully support the debugging information as generated
by your compiler.
− As an alternative to gdb and dbx, you can use ddd with Ladebug, as found on Compaq and DEC systems. Ladebug offers fewer features than gdb, and some of the more
advanced Ladebug features may not be supported by ddd. However, using Ladebug may
be useful if gdb or dbx do not understand or fully support the debugging information as
generated by your compiler.
1
− As another alternative to gdb, you can use ddd with the xdb debugger, as found on
hp-ux systems.
2
.
• To debug Java byte code programs, you can use ddd with jdb, the Java debugger, as of jdk
1.1 and later. (ddd has been tested with jdk 1.1 and jdk 1.2.)
• To debug Python programs, you can use ddd with pydb, a Python debugger.
• To debug Perl programs, you can use ddd with the Perl debugger, as of Perl 5.003 and later.
• To debug Bash programs, you need a version Bash that supports extended debugging support.
To get this enhanced version see http://bashdb.sourceforge.net. You will need
version 2.05b-debugger-0.32 or later to work with ddd.

Man Page in Linux


How to view same thing in different man page?????
How to read entire man page without knowing names of a particular command????

There are POSIX Programmer's Manual and Linux Programmer's Manual and Library Functions Manual


To find help on any commands based on what manpage packages have been installed.
qyang@lubuntu-laptop:~$ dpkg --list |grep manpage
ii  manpages                                                    3.74-1ubuntu1                              all          Manual pages about using a GNU/Linux system
ii  manpages-dev                                                3.74-1ubuntu1                              all          Manual pages about using GNU/Linux for development
ii  manpages-posix                                              2.16-1                                     all          Manual pages about using POSIX system
ii  manpages-posix-dev                                          2.16-1                                     all          Manual pages about using a POSIX system for development
#apt-get install manpages-posix manpages-posix-dev
#yum install man-pages
#yum install libstdc++-docs          to see man page of C++ library
$man pthreads
$man ldd
$man pthread_mutex_lock

$man std::iostream
$man std::vector
$man malloc

Shared Libraries Demo *.so file.



Ref 1 cmd line to generate *.so on stackoverflow
Ref 2 stackflow post ld --verbose -llibxxx

testsomain is smaller when not compiled with testso.c 
[q.yang@fedora20 Trash]$ gcc testsomain.c -o testsomain -L./ -ltestso
It's bigger when compiled with testso.c. It's one of the benefit of using dynamic library.
[q.yang@fedora20 Trash]$ gcc testsomain.c testso.c -o testsomain
testsomain.c
#include 
#include "testso.h"

int main(void)
{
  printf("Testing calling function in *.so \n");
  Ext_PrintHello();
}
testso.c
#include 

void Ext_PrintHello(void)
{
  printf("%s Invoked from external module.\n",__func__);
}
testso.h
//#error "this file has been included here"

void Ext_PrintHello(void);
Compile to generate dynamic library:
Note: MUST use -fPIC option PositionIndependantCode(PIC)
*.so file name must be libxxnamexx.so, cannot be xxnamexx.so
[q.yang@fedora20 Trash]$ gcc -shared -fPIC -o libtestso.so testso.c
Compile main program to load dynamic library *.so
[q.yang@fedora20 Trash]$ gcc testsomain.c -o testsomain -L./ -ltestso
Set load library search path
[q.yang@fedora20 Trash]$ LD_LIBRARY_PATH=./
[q.yang@fedora20 Trash]$ export LD_LIBRARY_PATH
Run program
[q.yang@fedora20 Trash]$ ./testsomain 
Testing calling function in *.so 
Ext_PrintHello Invoked from external module.
Checking so file dependencies $ldd and file info $file. (Running for i686 or ARM)
duser@10.1.1.8:~/Trash$ file libtestso.so 
libtestso.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, BuildID[sha1]=0xf54c8aad49c8dfd0220885eab40fe703c0e5495b, not stripped

duser@10.1.1.8:~/Trash$ ldd libtestso.so 
 libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb754b000)
 /lib/ld-linux.so.2 (0xb770f000)

We can also use linker $ld to check where system default search path for *.so shared library files. Given libtestso.so [Ref 2]
duser@10.1.1.8:~/Trash$ld -L./ -ltestso --verbose

..................
..................
==================================================
attempt to open /usr/i686-linux-gnu/lib32/libtestso.so failed
attempt to open /usr/i686-linux-gnu/lib32/libtestso.a failed
attempt to open /usr/local/lib32/libtestso.so failed
attempt to open /usr/local/lib32/libtestso.a failed
attempt to open /lib32/libtestso.so failed
attempt to open /lib32/libtestso.a failed
attempt to open /usr/lib32/libtestso.so failed
attempt to open /usr/lib32/libtestso.a failed
attempt to open /usr/local/lib/i386-linux-gnu/libtestso.so failed
attempt to open /usr/local/lib/i386-linux-gnu/libtestso.a failed
attempt to open /usr/local/lib/libtestso.so failed
attempt to open /usr/local/lib/libtestso.a failed
attempt to open /lib/i386-linux-gnu/libtestso.so failed
attempt to open /lib/i386-linux-gnu/libtestso.a failed
attempt to open /lib/libtestso.so failed
attempt to open /lib/libtestso.a failed
attempt to open /usr/lib/i386-linux-gnu/libtestso.so failed
attempt to open /usr/lib/i386-linux-gnu/libtestso.a failed
attempt to open /usr/lib/libtestso.so failed
attempt to open /usr/lib/libtestso.a failed
/usr/bin/ld.bfd.real: cannot find -ltestso
If we tell the load library path via -L option. Linker will find it.
duser@10.1.1.8:~/Trash$ ld -L./ -ltestso --verbose
....................
....................
==================================================
attempt to open .//libtestso.so succeeded
-ltestso (.//libtestso.so)
libc.so.6 needed by .//libtestso.so
found libc.so.6 at /lib/i386-linux-gnu/libc.so.6
ld-linux.so.2 needed by /lib/i386-linux-gnu/libc.so.6
found ld-linux.so.2 at /lib/i386-linux-gnu/ld-linux.so.2
/usr/bin/ld.bfd.real: warning: cannot find entry symbol _start; not setting start address

Wednesday, November 4, 2015

Sample code of recursive function in C/C++ (ToDo.....)

[1] www.cplusplus.com/Recursion

What needs to pay attention when creating safe recursive function?


Sample Codes of Thread Safe functions and variables (ToDo....)

The simplest method is to make your variables private (but you do that already, right?) and to use synchronized accessor methods. Accessor methods allow access to private member variables, but in a controlled manner. Take the following accessor methods, which provide a safe way to change the value of a counter.

 Here is how to make variable thread safe in java. Make it private and accessible via synchronized public function call.
public class MyCounter
{
private int count = 0; // count starts at zero

public synchronized void setCount(int amount)
{ 
count = amount;
}

public synchronized int getCount()
{
return count;
}
}


In C/C++, mutex, would be necessary.

Function Pointers in C/C++



#include <iostream>
#include <cstring>
#include <vector>

using namespace std;
namespace DemoFunPt {
typedef void (*CallBackFunc)(int i_input);
// Register callback function
vector<CallBackFunc> Callbackfuncs;

void Func_A(int i_input)
{
  cout<< "Hello from Func_A " << i_input << endl;
}

void Func_B(int i_input)
{
  cout<< "Hello from Func_B " << i_input << endl;
}

void RegisterCallbackFunc(CallBackFunc i_FuncPt)
{
  Callbackfuncs.push_back(i_FuncPt);
}

}

int  main()
{
   DemoFunPt::RegisterCallbackFunc(DemoFunPt::Func_A);
   DemoFunPt::RegisterCallbackFunc(DemoFunPt::Func_B);

   for(int i=0; i< DemoFunPt::Callbackfuncs.size(); i++){
      DemoFunPt::Callbackfuncs[i](i);
   }
   cout<<"Done demo" << endl;
   return 0;
}



root@trac ~# g++ funcpointer.cpp -o test
root@trac ~# ./test
Hello from Func_A 0
Hello from Func_B 1
Done demo

Sunday, November 1, 2015

exercises in python

---join
In [4]: a
Out[4]: ['1', '2', '3', '4']

In [6]: ',tail'.join(a)
Out[6]: '1,tail2,tail3,tail4'

--dictionary
In [20]: dict
Out[20]: {'H1': 'H1 UL1 [%]', 'H2': 'H2 UL1 [%]'}

In [21]: for i in dict: print dict[i]
H2 UL1 [%]
H1 UL1 [%]


 ---type
>> type([]) is list
True
>>> type({}) is dict
True
>>> type('') is str
True
>>> type(0) is int
True
>>> type({})

>>> type([])

>> type([]) is list
True
>>> type({}) is dict
True
>>> type('') is str
True
>>> type(0) is int
True
>>> type({})

>>> type([])


---utilities
In [3]: print int("0x3cf",0)  python hex to int

Auto start wanted application on Lubuntu log in.




Putting launcher into ~/.config/autostart. Ref
CreatAutoStartShell.py '' ''
./CreatAutoStartShell.py vncserverstart /home/qyang/startvncserver.sh
./CreatAutoStartShell.py startxcompmgr /home/qyang/startxcompmgr.sh
startvncserver.sh
#!/bin/bash
vncserver &
startxcompmgr.sh
#!/bin/bash
xcompmgr -n &
CreatAutoStartShell.py
#!/usr/bin/env python3
import os
import sys
home = os.environ["HOME"]

name = sys.argv[1]; command = sys.argv[2]

launcher = ["[Desktop Entry]", "Name=", "Exec=", "Type=Application", "X-GNOME-Autostart-enabled=true"]
dr = home+"/.config/autostart/"
if not os.path.exists(dr):
    os.makedirs(dr)
file = dr+name.lower()+".desktop"

if not os.path.exists(file):
    with open(file, "wt") as out:
        for l in launcher:
            l = l+name if l == "Name=" else l
            l = l+command if l == "Exec=" else l
            out.write(l+"\n")
else:
    print("file exists, choose another name")