Thursday, October 1, 2020
Automatically Login to Windows 10 without a password
Sunday, September 20, 2020
Allow an OBS session to automatically control a second OBS
Make PowerPoint control other applications using VBA
Here's some code that will let you use PowerPoint to run .BAT files
The basis of this code comes from Michael Kordahi's original post on his Linkedin account and OBS scripts page. I found this very helpful and wanted to post how to do it, plus possible improvements. I'm using it to control scenes in PowerPoint, but I've modified the code to use websockets.
Original post:
https://obsproject.com/forum/resources/powerpoint-slide-window-navigation-using-obs-hotkey.938/
And Linkedin Post of an example:
I've modified Michael's code slightly from above, as I want it to call a .BAT. (his sent CTRL+ hotkey commands which also worked, but I needed to run power point from a different computer so i needed change it slightly)
In my case, I'm running PowerPoint, and as I advance slides, I want it to automatically send a command (via .BAT) to OBS Studio running on another computer, and I'm doing it in conjunction with WebSockets
https://obsproject.com/forum/resources/command-line-tool-for-obs-websocket-plugin-windows.615/
So here is what happens.
As the slides advance, based on the FIRST line of text on the "Notes Description" on the PowerPoint slide, that will trigger the execution of a .BAT file.
This bat file sends a command to the computer running OBS to switch to a specific scene.
Diagram, PowerPoint has "OBS3" for a description. Sends that to the OBS computer, which triggers a scene to automatically be displayed.
Now as I advance through PowerPoint, specific scenes will automatically occur. I use this in a house of worship situation where I want to reduce the load of the worship team.
Here's how to make it work.
First install the WebSockets app on your OBS computer. You'll also want to install it on PowerPoint computer (assuming they are different machines).
A suggest program to also install is NOOBS https://obsproject.com/forum/resources/nuttys-official-obs-commander-noobs-cmdr.1178/ which will greatly aid in the creation of the .BAT script for you.
4> Create or load a PowerPoint presentation.
5> Goto DEVELOPER -> MACROS
or
VIEW -> MACROS
6> in "macro name" call it OnSlideShowPageChange
Then click on "CREATE"
You'll see this:
Sub OnSlideShowPageChange()
End Sub
7> Make it look like this:
Sub OnSlideShowPageChange()
Dim i As Integer
Dim sNotes As String
Dim sKey As String
i = ActivePresentation.SlideShowWindow.View.CurrentShowPosition
s = Left(ActivePresentation.Slides(i).NotesPage.Shapes.Placeholders(2).TextFrame.TextRange.Text, 4)
If Left(s, 3) = "OBS" Then
sKey = Right(s, 1)
Shell ("CMD.EXE /c C:\OBSCommand\" & sKey & ".bat")
AppActivate ("PowerPoint")
End If
End Sub
8> Please note the C:\OBSCommand\ should reflect the path that you are storing your BAT files in for this.
9> Now in your presentation "NOTES" put OBS1 or OBS2 or OBS3 on the first line. This will correspond to the scenes.
In the example below, I have "OBS3" which, in the case of the example, the white screen on the left, when power point displays it, will call to run a bat file for "OBS3"
In this example, the script will check the first line for it to begin with OBS, then it will take the trailing number, which will be a "3"
10> now Launch NOOB
I've put in my server IP of my OBS box, I've put in the port and password. Now click on the left most button "Not Connected" to imitate a connection
If successful, you should be able to now click on "SCENE" and then in the box next to "Switch To" you should be able to see all available scenes.
Once you have selected a scene, you can run "TEST COMMAND" and, if everything is configured, your scene should change in OBS.
Now export that command, and save it with a value of 1-9, in my example I saved it as "3"
10> Now start your PP presentation (F5)
11> Make sure that OBS is running with your scenes, and change the slides in PowerPoint, you should see the images change in OBS
Thursday, July 23, 2020
OpenShot - Adding a title
Select "TITLE" at the top, pick a title template that you like. (or press CTRL+T )
Open Shot - Speeding up editing playback
Wednesday, June 10, 2020
Wednesday, April 15, 2020
Bash fundamentals
Bash scripting language
#!/bin/bash
at the top of the file.$ chmod u+x scriptname
./scriptname
and pass any parameters you wish.#!/path/to/interpreter
./bin/bash
) on the file itself.#!
method is why many scripting languages use #
for comments#!/bin/bash # Use $1 to get the first argument: echo $1
Comments
#
and run to the end of the line:echo Hello, World. # prints out "Hello, World."
Variables/Arrays
=
:foo=3 # sets foo to 3
foo = 3 # error: invokes command `foo' with arguments `=' and `3'
((
and ))
:(( foo = 3 )) # Sets foo to 3.
$
:echo $foo ; # prints the value of foo to stdout
unset
:foo=42 echo $foo # prints 42 unset foo echo $foo # prints nothing
foo=$bar # assigns the value of $bar to foo.
# wrong: foo=x y z # sets foo to x; will try to execute y on z # right: foo="x y z" # sets foo to "x y z"
echo ${foo} # prints $foo
foo[0]="first" # sets the first element to "first" foo[1]="second" # sets the second element to "second"
foo[0]="one" foo[1]="two" echo ${foo[1]} # prints "two"
foo[0]="one" foo[1]="two" echo $foo # prints "one"
foo=("a a a" "b b b" "c c c") echo ${foo[2]} # prints "c c c" echo $foo # prints "a a a"
@
or *
:array=(a b c) echo $array # prints a echo ${array[@]} # prints a b c echo ${array[*]} # prints a b c
@
, surround it with quotes, and surround that with parentheses:foo=(a b c) bar=("${foo[@]}") echo ${bar[1]} # prints b
foo=(a b c) bar=$foo echo ${bar[1]} # prints nothing
foo=("a 1" "b 2" "c 3") bar=(${foo[@]}) baz=("${foo[@]}") echo ${bar[1]} # oops, print "1" echo ${baz[1]} # prints "b 2"
Special variables
echo $0 # prints the script name echo $1 # prints the first argument echo $2 # prints the second argument echo $9 # prints the ninth argument echo $10 # prints the first argument, followed by 0 echo ${10} # prints the tenth argument echo $# # prints the number of arguments
$?
holds the "exit status" of the previously executed process.true
is a program that always "succeeds," and false
is a program that always "fails":true echo $? # prints 0 false echo $? # will never print 0; usually prints 1
$$
$!
:# sort two files in parallel: sort words > sorted-words & # launch background process p1=$! sort -n numbers > sorted-numbers & # launch background process p2=$! wait $p1 wait $p2 echo Both files have been sorted.
Operations on variables
String replacement
foo="I'm a cat." echo ${foo/cat/dog} # prints "I'm a dog."
foo="I'm a cat, and she's cat." echo ${foo/cat/dog} # prints "I'm a dog, and she's a cat." echo ${foo//cat/dog} # prints "I'm a dog, and she's a dog."
foo="hello" echo ${foo/hello/goodbye} # prints "goodbye" echo $foo # still prints "hello"
foo="I like meatballs." echo ${foo/balls} # prints I like meat.
${name#pattern}
operation removes the shortest prefix of ${name}
matching pattern
, while ##
removes the longest:minipath="/usr/bin:/bin:/sbin" echo ${minipath#/usr} # prints /bin:/bin:/sbin echo ${minipath#*/bin} # prints :/bin:/sbin echo ${minipath##*/bin} # prints :/sbin
%
is the same, except for suffixes instead of prefixes:minipath="/usr/bin:/bin:/sbin" echo ${minipath%/usr*} # prints nothing echo ${minipath%/bin*} # prints /usr/bin: echo ${minipath%%/bin*} # prints /usr
String/array manipulation
#
counts the number of characters in a string or the number of elements in an array.It is a common mistake to accidentally operate on the first element of an array as a string, when the intent was to operate on the array.
ARRAY=(one two three) echo ${#ARRAY} # prints 3 -- the length of the array?
ARRAY=(a b c) echo ${#ARRAY} # prints 1
${#ARRAY}
is the same as ${#ARRAY[0]}
, which counts the number of characters in the first element, a
.@
:ARRAY=(a b c) echo ${#ARRAY[@]} # prints 3
string="I'm a fan of dogs." echo ${string:6:3} # prints fan array=(a b c d e f g h i j) echo ${array[@]:3:2} # prints d e
Existence testing
unset username echo ${username-default} # prints default username=admin echo ${username-default} # prints admin
:
"):unset foo
unset bar echo ${foo-abc} # prints abc echo ${bar:-xyz} # prints xyz foo="" bar="" echo ${foo-123} # prints nothing echo ${bar:-456} # prints 456
=
(or :=
) is like the operator -
, except that it also sets the variable if it had no value:unset cache echo ${cache:=1024} # prints 1024
echo $cache # prints 1024 echo ${cache:=2048} # prints 1024 echo $cache # prints 1024
+
operator yields its value if the variable is set, and nothing otherwise:unset foo
unset bar foo=30 echo ${foo+42} # prints 42 echo ${bar+1701} # prints nothing
?
crashes the program with the specified message if the variable is not set:: ${1?failure: no arguments} # crashes the program if no first argument
:
command ignores all of its arguments, and is equivalent to true
.)Indirect look-up
!
prefix operator.${!expr}
behaves like ${${expr}}
, if only that worked:foo=bar bar=42 echo ${!foo} # prints $bar, which is 42 alpha=(a b c d e f g h i j k l m n o p q r s t u v w x y z) char=alpha[12] echo ${!char} # prints ${alpha[12]}, which is m
Array quirks: * versus @
$*
and $@
.${array[*]}
or ${array[@]}
as well.]The both seem to contain the arguments passed to the current script/procedure, but they have subtly different behavior when quoted:
print12
:#!/bin/bash # prints the first parameter, then the second: echo "first: $1" echo "second: $2"
showargs
:#!/bin/bash echo $* echo $@ echo "$*" echo "$@" bash print12 "$*" bash print12 "$@"
showargs
:$ bash showargs 0 " 1 2 3"
0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 first: 0 1 2 3 second: first: 0 second: 1 2 3
"$*"
combines all arguments into a single string, while "$@"
requotes the individual arguments.IFS
(internal field separator) is set, then the contents of this variable are spliced between elements in "$*"
.atvstar
:#!/bin/bash IFS="," echo $* echo $@ echo "$*" echo "$@"
$ bash atvstar 1 2 3
1 2 3 1 2 3 1,2,3 1 2 3
IFS
must contain a single character.*
or @
:arr=("a b" " c d e") echo ${arr[*]} # prints a b c d e echo ${arr[@]} # prints a b c d e echo "${arr[*]}" # prints a b c d e echo "${arr[@]}" # prints a b c d e bash print12 "${arr[*]}" # prints: # first: a b c d e # second: bash print12 "${arr[@]}" # prints: # first: a b # second: c d e
Strings and quoting
world=Earth foo='Hello, $world!' bar="Hello, $world!" echo $foo # prints Hello, $world! echo $bar # prints Hello, Earth!
In intepolated strings, variables are converted to their values.
Scope
foo=42 bash somescript # somescript cannot see foo export foo bash somescript # somescript can see foo echo "foo = " $foo # always prints foo = 42
Let's suppose that this is
somescript
:#!/bin/bash echo "old foo = $foo" foo=300 echo "new foo = $foo"
old foo = new foo = 300 old foo = 42 new foo = 300 foo = 42
Expressions and arithmetic
expr
prints the result of arithmetic expressions, but one must take caution:expr 3 + 12 # prints 15 expr 3 * 12 # (probably) crashes: * expands to all files expr 3 \* 12 # prints 36
The
(( assignable = expression ))
assignment notation is more forgiving:(( x = 3 + 12 )); echo $x # prints 15 (( x = 3 * 12 )); echo $x # prints 36
If you want the result of an arithmetic expression without assigning it, you can use
$((expression))
:echo $(( 3 + 12 )) # prints 15 echo $(( 3 * 12 )) # prints 36
While declaring variables implicitly is the norm in bash, it is possible to declare variables explicitly and attach a type to them.
The form
declare -i variable
creates an explicit integer variable:declare -i number number=2+4*10 echo $number # prints 42 another=2+4*10 echo $another # prints 2+4*10 number="foobar" echo $number # prints 0
Assignments to integer variables will force evaluation of expressions.
Files and redirection
When writing to STDOUT, the output appears (by default) at the console.
When reading from STDIN, it reads (by default) directly from what the user types into the console.
When writing to STDERR, the output appears (by default) at the console.
For instance, to dump the contents of a file into STDIN (instead of accepting user input), use the
<
operator:# prints out lines in myfile containing the word foo: grep foo < myfile
To dump the output of a command into a file, use the
>
operator:# concatenates file1 with file2 in new file combined:cat file1 file2 > combined
To append to the end of a file, use the
>>
operator:# writes the current date and time to the end of a file named log:date >> log
To specify the contents of STDIN literally, in a script, use the
<<endmarker
notation:cat <<UNTILHERE
All of this will be printed out. Since all of this is going into cat on STDIN. UNTILHERE
Everything until the next instance of
endmarker
by itself on a line is redirected to STDIN.2>
:# writes errors from web daemon start-up to an error log:httpd 2> error.log
In fact, all I/O channels are numbered, and
>
is the same as 1>
.M>&N
redirects the output of channel M to channel N.So, it's straightforward to have errors display on STDOUT:
grep foo nofile 2>&1 # errors will appear on STDOUT
Capturing STDOUT with backquotes
``
.# writes the date and the user to the log: echo `date` `whoami` >> log
$(command)
:# writes the date and the user to the log: echo $(date) $(whoami) >> log
`cat path-to-file`
, but there is a simpler built-in shorthand: `<path-to-file`
:echo user: `<config/USER` # prints the contents of config/USER
Redirecting with exec
exec
can manipulate channels over ranges of commands:exec < file # STDIN has become file exec > file # STDOUT has become file
exec 7<&0 # saved STDIN as channel 7 exec 6>&1 # saved STDOUT as channel 6
exec 6>&1 # saved STDOUT as channel 6 exec > LOGFILE # all further output goes to LOGFILE # put commands here exec 1>&6 # restores STDOUT; output to console again
Pipes
|
(pipe) operator:# prints out root's entry in the user password database: cat /etc/passwd | grep root
outputing-command | inputing-command
# A one-liner to find space hogs in the current directory: # du -cks * # prints out the space usage # of files in the current directory # sort -rn # sorts STDIN, numerically, # by the first column in reverse order # head # prints the first 10 entries from STDIN du -cks * | sort -rn | head
<(command)
form.<(command)
expands into the name of a temporary file that contains the output of running command
.# appends uptime, date and last line of event.log onto main.log: cat <(uptime) <(date) <(tail -1 event.log) >> main.log
Processes
&
postfix operator:time-consuming-command &
$!
special variable directly after spawning the process:time-consuming-command & pid=$!
wait
command waits for a process id's associated process to finish:time-consuming-command & pid=$! wait $pid echo Process $pid finished.
wait
waits for all child processes to finish.for f in *.jpg do convert $f ${f%.jpg}.png & done wait echo All images have been converted.
Globs and patterns
echo *.txt # prints names of all text files echo *.{jpg,jpeg} # prints names of all JPEG files
*
matches any string.?
matches a single character.[chars]
matches any character inchars
.[a-b]
matches any character betweena
andb
.
fileNNN
, where NNN
is some 3-digit number:rm file[0-9][0-9][0-9]
{string1,string2,...,stringN}
expands to string1
or string2
or ...echo {0,1} # prints 0 1 echo {0,1}{0,1} # prints 00 01 10 11 echo {0,1}{0,1}{0,1} # prints 000 001 010 011 100 101 110 111
Control structures
Conditionals
# this will print: if true then echo printed fi # this will not print: if false then echo not printed fi
if httpd -k start then echo "httpd started OK" else echo "httpd failed to start" fi
test
.help test
to list them all.-e file
is true iff a specific file/directory exists.-z string
is true iff the given string is empty.string1 = string2
is true iff the two strings are equal.
test args
using square brackets: [ args ]
.if [ "$1" = "-v" ] then echo "switching to verbose output" VERBOSE=1 fi
Iteration
while command; do commands; done
form executes commands
until the test command completes with non-zero exit status:# automatically restart the httpd in case it crashes: while true do httpd done
for var in array; do commands; done
loop:# compile all the c files in a directory into binaries: for f in *.c do gcc -o ${f%.c} $f done
Subroutines
function name { commands }
name () { commands }
$n
for the nth argument.count=20 function showcount { echo $count count=30 } showcount # prints 20 echo $count # prints 30
Examples
function fact { result=1 n=$1 while [ "$n" -ge 1 ] do result=$(expr $n \* $result) n=$(expr $n - 1) done echo $result }
function facter { result=1 n=$1 while (( n >= 1 )) do (( result = n * result )) (( n = n - 1 )) done echo $result }
factered () { declare -i result declare -i n n=$1 result=1 while (( n >= 1 )) do result=n*result n=n-1 done echo $result }
Tuesday, April 14, 2020
Bash Grep Multiple Pattern matching
The grep command supports regular expression pattern. To search multiple patterns, use the following syntax:
- Use single quotes in the pattern: grep 'pattern*' file1 file2
- Next use extended regular expressions: egrep 'pattern1|pattern2' *.py
- Finally, try on older Unix shells/oses: grep -e pattern1 -e pattern2 *.pl
Grep searching two words in a line
grep 'word1\|word2\|word3' /path/to/file
### Search all text files ###
grep 'word*' *.txt
### Search all python files for 'wordA' or 'wordB' ###
grep 'wordA*'\''wordB' *.py
grep -E 'word1|word2' *.doc
grep -e string1 -e string2 *.pl
egrep "word1|word2" *.c
Examples
$ grep 'warning\|error\|critical' /var/log/messages
To just match words, add the -w option:
$ grep -w 'warning\|error\|critical' /var/log/messages
Use the egrep command and you can skip the above syntax to search three words:
$ egrep -w 'warning|error|critical' /var/log/messages
How to find multiple strings in files?
$ grep -e 'warning\|error\|critical' /var/log/messages
I recommend that you pass the -i (ignore case) and --color option as follows too:
$ egrep -wi --color 'warning\|error\|critical' /var/log/messages
# egrep -wi --color 'foo|bar' /etc/*.conf
# egrep -Rwi --color 'foo|bar' /etc/
- -R : Recursive search
- -w : Match only words
- -i : Ignore case distinctions. In other words match FOO, foo, Foo and so on.
- --color : Surround the matched in color on the terminal. For example, display matched strings in colors.
Bash Condition Comparisons
Compare Numbers, Strings and Files in Bash Shell Script
if [ conditions/comparisons] then commands fi
if [2 -gt 3] then print "2 is greater" else print "2 is not greater" fi
Numeric Comparisons
VAL1 -ge VAL2 is VAL1 is greater than or equal to VAL2
VAL1 -gt VAL2 is VAL1 is greater than VAL2
VAL1 -le VAL2 is VAL1 is less than or equal to VAL2
VAL1 -lt VAL2 is VAL1 is less than VAL2
VAL1 -ne VAL2 is VAL1 is not equal to VAL2
#!/bin/bash # Script to do numeric comparisons var1=10 var2=20 if [ $var2 -gt $var1 ] then echo "$var2 is greater than $var1" fi # Second comparison If [ $var1 -gt 30] then echo "$var is greater than 30" else echo "$var1 is less than 30" fi
Strings Comparisons
VAL1 != VAL2 checks if VAL1 is not the same as VAL2
VAL1 < VAL2 checks if VAL1 is less than VAL2
VAL1 > VAL2 checks if VAL1 is greater than VAL2
-n VAL1 checks if VAL1 has a length greater than zero
-z VAL1 checks if VAL1 has a length of zero
#!/bin/bash # Script to do string equality comparison name=linuxtechi if [ $USER = $name ] then echo "User exists" else echo "User not found" fi # script to check string comparisons var1=a var2=z var3=Z if [ $var1 \> $var2 ] then echo "$var1 is greater" else echo "$var2 is greater" fi # Lower case & upper case comparisons if [ $var3 \> $var1 ] then echo "$var3 is greater" else echo "$var1 is greater" fi
#!/bin/bash # Script to see if the variable holds value or not var1=" " var2=linuxtechi if [ -n $var1 ] then echo "string is not empty" else echo "string provided is empty" fi
File comparison
-e file checks if the file exists on system
-w file checks if the file exists on system and if it is writable
-r file checks if the file exists on system and it is readable
-s file checks if the file exists on system and it is not empty
-f file checks if the file exists on system and it is a file
-O file checks if the file exists on system and if it’s is owned by the current user
-G file checks if the file exists and the default group is the same as the current user
-x file checks if the file exists on system and is executable
file A -nt file B checks if file A is newer than file B
file A -ot file B checks if file A is older than file B
#!/bin/bash # Script to check file comparison dir=/home/linuxtechi if [ -d $dir ] then echo "$dir is a directory" cd $dir ls -a else echo "$dir is not exist" fi