-
Notifications
You must be signed in to change notification settings - Fork 17
/
notes.txt
469 lines (362 loc) · 18 KB
/
notes.txt
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
---------------------------------------------------------------------------------------------------
Additional softwares after a fresh Linux installation:
super-boot-manager (http://www.sourceslist.eu/projects/super-boot-manager)
sudo add-apt-repository ppa:ingalex/super-boot-manager
sudo apt-get update
sudo apt-get install super-boot-manager
---------------------------------------------------------------------------------------------------
running a simple HTTP server:
(http://www.linuxjournal.com/content/tech-tip-really-simple-http-server-python)
python -m SimpleHTTPServer
connect using: http://127.0.0.1:8000/tmp
---------------------------------------------------------------------------------------------------
Installing perl modules:
------------------------
Many perl scripts use modules (e.g. `use Archive::Ar;`). To install missing modules, use cpanm.
- sudo apt-get install cpanminus
- cpanm Archive::Ar
cpanm would normally automatically install all the dependencies also. Without 'sudo' installation
will happen to a directory in your home directory (e.g. /home/gautam/perl5).
Sometimes, installation fails (usually because some dependency could not be automatically
installed). In this case, find the dependency whose installation failed (using the log file whose
location would be helpfully indicated by cpanm) and install the dependency manually. For example, if
'Test::Exception' is a dependency whose automatic installation failed, then just run
- cpanm Test::Exception
Then retry the original installation.
Finally, to run the perl script that was using the newly installed modules, you need to specify the
location of the newly installed modules using,
- export PERL5LIB=/home/gautam/perl5/lib/perl5
---------------------------------------------------------------------------------------------------
To cut the last field (using space as delimiter):
awk -F" " '{print $NF}'
OR
rev | cut -d" " -f1 | rev
To print the 3rd field using awk:
echo "a b c d e" | awk '{print $3}'
To remove leading whitespace:
echo " blah" | awk '{$1=$1};1'
To squeeze/compress multiple spaces into one:
echo "hey there" | tr --squeeze-repeats " "
---------------------------------------------------------------------------------------------------
Alternative way to do:
for file in `ls`; do echo $file; done
is:
ls | while read file; do echo $file; done
---------------------------------------------------------------------------------------------------
copy contents of a file into the clipboard:
-------------------------------------------
cat file | xclip -in -selection clipboard // puts into the Ctrl+Shift+V clipboard
OR
cat file | xclip // puts into the Shift+Insert (middle mouse-button clipboard)
---------------------------------------------------------------------------------------------------
list files with blank lines at the end:
---------------------------------------
for F in `ls {src,test}/**/*.d`; do S=$(tail -1 ${F}); [ -z ${S} ] && echo ${F}; done
---------------------------------------------------------------------------------------------------
To get the sizes of files (without an overwhelming amount of output), use:
du -ckhs *
(I don't yet know the reason for the 'k', as 'du -chs *' seems to give the same output)
---------------------------------------------------------------------------------------------------
To get the amount of disk space used & free:
df -hT | egrep -i "file|^/"
---------------------------------------------------------------------------------------------------
To grep for tabs in a file
grep $'\t' <filename>
---------------------------------------------------------------------------------------------------
The output of 'echo' can be controlled by using certain "Terminfo Capabilities", e.g:
prompt$> tput smso; echo "hello world"; tput rmso
(more here: http://tldp.org/LDP/lpg/node126.html)
---------------------------------------------------------------------------------------------------
To run a command at startup, there are 2 options:
1. sudo crontab -e
add the following in the end:
@reboot <<command_to_run>>
OR
2. create a script file with your command
make the script executable
sudo /etc/rc.local
path to your script at the end just above exit 0
So what's the difference?
For the most part they're equivalent. The part where they differ is precisely when they run the
command. /etc/rc.local is the last item to run, after all the other services have started.
I don't yet know when @reboot runs.
---------------------------------------------------------------------------------------------------
[15:47:45] Nemanja Boric: btw, good thing for debugging: setarch i686 -R gdb ./program
[15:47:51] Nemanja Boric: removes address randomization
---------------------------------------------------------------------------------------------------
To cherry-pick all commits on a branch on top of another branch:
----------------------------------------------------------------
Goal: cherry-pick source_branch commits over target_branch
(i.e. commits Cy & Cz over commit C6)
C6 o => target_branch
|
C5 o o Cz => source_branch
| |
C4 o o Cy
| |
C3 o o Cx => some_intermediate_branch
| |
C2 o---
|
C1 o
1. git checkout target_branch
2. git rebase --onto HEAD Cx source_branch
(commit Cx will not be picked - only commits Cy & Cz will be picked and applied above
commit C6)
(if instead of source_branch, only the commit hash was used, i.e. Cz, then source_branch
will not be moved from its original location)
---------------------------------------------------------------------------------------------------
Setting date from the command-line:
-----------------------------------
sudo date MMDDHHMMYYYY.SS
| |
month minutes
---------------------------------------------------------------------------------------------------
Expandable GitHub comments:
<details>
<summary>Click to expand</summary>
<--- this blank line is necessary for proper formatting
whatever
</details>
---------------------------------------------------------------------------------------------------
Installing a package on Arch Linux from AUR:
--------------------------------------------
- download the package archive from AUR ("Download snapshot" link in the
"Package Actions" box on the right) to `~/aur`
- extract the archive, then delete it
- cd to the extracted directory
- makepkg -Acs
- sudo pacman -U <tar.xz>
---------------------------------------------------------------------------------------------------
If you need to use different GitHub accounts on the same computer:
------------------------------------------------------------------
The idea is to present different ssh keys to GitHub for the different
accounts.
- use different git remote URLs of the form:
git@github-BLAH:...
(where BLAH is a decent descriptive string)
- add a section in `~/.ssh/config` of the form:
```
Host github-BLAH
Hostname github.com
User git
IdentityFile ~/.ssh/id_ed25519_blah <-- path to proper ssh key
IdentitiesOnly yes
```
This may be helpful if you run into problems:
http://code.tutsplus.com/tutorials/how-to-work-with-github-and-multiple-accounts--net-22574
---------------------------------------------------------------------------------------------------
To run an SFTP server in a docker container:
--------------------------------------------
USERNAME="user"
PASSWORD="password"
HOST_DIR_TO_SHARE="/path/to/shared/directory"
DIR_IN_CONTAINER="/home/${USERNAME}/share"
docker run -d -v "${HOST_DIR_TO_SHARE}:${DIR_IN_CONTAINER}" -p "2222:22" atmoz/sftp:alpine ${USERNAME}:${PASSWORD}:1001
testing:
confirm the container is running and get its name using `docker ps`
CONTAINER_NAME="..."
IP_ADDR=$(dcipaddr ${CONTAINER_NAME})
sftp ${USERNAME}@${IP_ADDR}
enter ${PASSWORD} when prompted
ls, get etc.
if you want other options e.g. logging in with SSH keys only etc., check out https://hub.docker.com/r/atmoz/sftp
---------------------------------------------------------------------------------------------------
Check in Makefile if docker container is already running:
---------------------------------------------------------
check:
@set -e; \
CONTAINER_NAME=blah; \
if [ `docker ps --quiet --filter status=running --filter name=$${CONTAINER_NAME}` ]; then \
echo "Container '$${CONTAINER_NAME}' is running." && false; \
fi
---------------------------------------------------------------------------------------------------
To create a password protected archive:
---------------------------------------
1. Generate a password (e.g. using `gopass generate -p tmp`)
1. Create a file (say `/tmp/password.txt`) containing the following line
```
PASSWORD=<the-generated-password>
```
1. export $(xargs < /tmp/password.txt)
1. 7z a archive_name.7z * -p${PASSWORD}
(here `*` makes all files in the directory to be added to the archive.
Individual file names can also be specified if necessary.)
---------------------------------------------------------------------------------------------------
Installing the Tela grub theme:
-------------------------------
This is needed only if you use grub as the bootloader. You'd use grub as the
bootloader only if EFI isn't supported (because otherwise you'd simply use
rEFInd).
1. Go to https://www.gnome-look.org/p/1307852/
1. Go to the `Files` tab and download `Tela-1080p.tar.xz`
1. extract Tela-1080p.tar.xz
1. cd Tela-1080p
1. sudo ./install.sh
1. reboot
---------------------------------------------------------------------------------------------------
Workaround for journalctl not accepting ISO8601 times:
------------------------------------------------------
➜ SINCE=$(date -d '2021-01-01T13:00:00' +%s)
➜ sudo journalctl --since=@${SINCE} --unit=whatever.service
---------------------------------------------------------------------------------------------------
## To give SSH access from outside the home network
1. Set up dyn-dns so the remote end doesn't need to always know the present
public IP address
1. Enable port-forwarding on the router (SSH uses port 22)
1. Set up a guest account
1. sudo systemctl start sshd
1. Connect from outside using `ssh guest@<dyn-dns-domain>`
---------------------------------------------------------------------------------------------------
## Enabling port-forwarding on the router
1. Login to router
1. Left column -> Internet -> Freigaben
1. Click the button `Gerät für Freigaben hinzufügen`
1. If the device exists under `Gerät`, choose it and confirm the IP address; if
it doesn't choose `IP Adresse manuell eingeben` and manually enter the IP
address
1. Click the button `Neue Freigabe` on the bottom right
1. Under Anwendung, choose `Andere Anwendung`
1. Under Bezeichnung, enter `SSH`
1. Under Protokoll, choose `TCP`
1. Under Port an Gerät, enter von 22 bis 22
1. Under Port extern gewünscht, also enter 22
1. Confirm that `Freigabe aktivieren` is checked, and select
`Internetzugriff über IPv4 und IPv6`
1. Click OK
1. Again click OK
---------------------------------------------------------------------------------------------------
## Accessing a hard-disk connected to the router
1. Login to router
1. Left column -> Heimnetz -> Speicher (NAS)
1. Under `Speicher (NAS) aktiv`, click on `USB-Speicher`
1. Click on the hard-disk folder (which should be the last entry on the page)
## To stream a video
1. Find the video you want to stream
1. Right-click -> Freigeben
1. Copy the download link
1. Open VLC media player
1. Media -> Open Network Stream
1. Paste the link
1. It may show some errors about invalid certificate, which you can safely
ignore
1. Enjoy
---------------------------------------------------------------------------------------------------
bash script confirmation:
-------------------------
empty means "No":
read -p "Continue? (y/N): " YES_OR_NO
[ -z "${YES_OR_NO}" ] || [[ "${YES_OR_NO}" != [yY] ]] && echo "Canceled." && exit 1
empty means "Yes":
read -p "Continue? (Y/n): " YES_OR_NO
if [ ! -z "${YES_OR_NO}" ]; then
[[ "${YES_OR_NO}" != [yY] ]] && echo "Canceled." && exit 1
fi
In zsh scripts, change `read -p "Continue? ...` to `read "?Continue? ...`
IOW, remove the `-p` option, and prefix a `?` to the prompt.
---------------------------------------------------------------------------------------------------
truncating long strings in a Go program:
----------------------------------------
trunc := func(s string, max int) string {
if len(s) <= max {
return s
}
delta := len(s) - max
suffix := "s"
if delta == 1 {
suffix = ""
}
// Note: The "plus N more characters" suffix that is added when truncating
// the string causes the final string to not really respect the specified
// maximum limit. This should be properly handled if this ever becomes a
// first-class utility function.
return fmt.Sprintf("%s <plus %d more character%s>", s[:max], delta, suffix)
}
str := "... a really long string ..."
truncateTo := 100
fmt.Println(trunc(str, truncateTo))
---------------------------------------------------------------------------------------------------
printing an io.Reader in a Go program:
--------------------------------------
buf := new(strings.Builder)
io.Copy(buf, reqBody) // reqBody is an io.Reader
fmt.Println(buf.String())
---------------------------------------------------------------------------------------------------
when dealing with Go channels:
------------------------------
. when declaring/passing channels, always specify whether it'll be used for
reading/writing
. the function writing into a channel should be responsible for closing it
(because only the writer knows when it is done writing)
. when reading from a channel, prefer to use `for r := range channelNameCh { ... }`
* send to nil channel --> blocks forever
* receive from nil channel --> blocks forever
* send to closed channel --> panic
* receive from closed channel --> immediately returns zero value
---------------------------------------------------------------------------------------------------
when dealing with Goroutines:
-----------------------------
. telling a goroutine to finish up:
if the goroutine is already reading from a channel:
simply close the channel
else:
give the goroutine a done channel, and close that
. when a goroutine finishes, it needs to signal its completion
if the goroutine is already writing into a channel:
simply close the channel
else:
defer wg.Done() (or defer doneFn())
---------------------------------------------------------------------------------------------------
Converting wav files to mp3 (ripping a cd):
--------------------------------------------
1. Plug-in the CD drive containing the CD
2. Open a terminal at that location
a simple way would be to open the directory in nautilus, right-click -> Open in Terminal
(the last time the path was `/run/user/1000/gvfs/cdda:host=sr0`)
3. Create a temporary directory to save the output files - `D=$(mktemp -d)`
4. for F in *.wav; do ffmpeg -i ${F} -vn -ar 44100 -ac 2 -b:a 192k ${D}/${F%.wav}.mp3; done
5. cd ${D}
6. [Optional] Convert spaces in filenames to underscores
for F in *; do NEW_NAME=$(echo ${F} | sed 's/\s/_/g'); mv ${F} ${NEW_NAME}; done
7. Play the files saved in $D to check if they're OK
---------------------------------------------------------------------------------------------------
Using grep in a shell script with 'set -euo pipefail':
------------------------------------------------------
In a shell script that uses 'set -euo pipefail', some extra work needs to be
done when using grep (in cases where the pattern being searched for not existing
is not an error condition). Or else, the script would immediately exit if the
pattern being searched for doesn't exist in the file.
In this case, a '||' is used after the grep command so that the line as a whole
always succeeds. The status of the grep command is later checked to determine
the next course of action.
According to
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html#tag_20_55_14,
grep's status codes have the following meaning:
0 => pattern was found
1 => pattern was not found
>1 => some error occurred
Here's a sample code snippet:
GREP_STATUS=-1
grep --silent pattern file || GREP_STATUS=$?
if [ ${GREP_STATUS} -eq 1 ]; then
# Do whatever needs to be done if the pattern was not found
elif [ ${GREP_STATUS} -gt 1 ]; then
exit ${GREP_STATUS}
fi
# Do whatever needs to be done if the pattern was found
---------------------------------------------------------------------------------------------------
RabbitMQ general info:
https://stackoverflow.com/a/48770082/793930
---------------------------------------------------------------------------------------------------
On Microsoft SQL Server database:
---------------------------------
To find the current max ID:
SELECT MAX([Id]) FROM <TABLE_NAME>
To check what the next ID will be:
SELECT IDENT_CURRENT('<TABLE_NAME>') + IDENT_INCR('<TABLE_NAME>') AS NextIdentityValue;
(if you get NULL, check if you've inserted the correct table name in both places)
To set the next ID:
DBCC CHECKIDENT ('<TABLE_NAME>', RESEED, <CURRENT_MAX_ID>);
|
└-> a row with this ID should already exist
---------------------------------------------------------------------------------------------------