SHIFT

--- Sjoerd Hooft's InFormation Technology ---

User Tools

Site Tools


Sidebar

Recently Changed Pages:

View All Pages


View All Tags


LinkedIn




WIKI Disclaimer: As with most other things on the Internet, the content on this wiki is not supported. It was contributed by me and is published “as is”. It has worked for me, and might work for you.
Also note that any view or statement expressed anywhere on this site are strictly mine and not the opinions or views of my employer.


Pages with comments

View All Comments

linuxtips

Notes, Tips & Tricks: Linux

This is a notes page, extended with tips & tricks. This page is not really documentation, just stuff for me to remember. Sometimes things will get removed from these pages and turned into real documentation, sometimes not. You might find these notes to come in hand, maybe not. For me, it's just things I don't want to forget.

Finding MD5 Hash on Linux

Find the MD5 hash of files on Linux by entering the command below and replace the “Your-File-Here” with the name of the file:

echo -n "Your-File-Here" | md5sum

Version info

You can check the original release version by displaying the /etc/SuSE-release file:

SHIFT:/ # cat /etc/SuSE-release
SUSE Linux Enterprise Server 10 (i586)
VERSION = 10
PATCHLEVEL = 2

Versie Commands

uname -r
        Kernel versie
uname -a
        Alle info

Runlevel info

This is the runlevel config as defined on SuSE:

  • 0 System halt
  • 1 Single user mode
  • 2 Local multiuser mode zonder netwerk
  • 3 Full multiuser mode met netwerk
  • 4 Niet gebruikt
  • 5 Full multiser met netwerk en GUI
  • 6 System Reboot

The default runlevel is set in /etc/inittab.

When the box is already running you can issue the command

"init x" 

while replacing the x for the appropriate runlevel number to change the runlevel. If you want to change the runlevel while booting issue the same command as a boot parameter.

Functie Toetsen

<CTRL>+d Stoppen met invoer
<CTRL>+c Beëindigen van programma
<CTRL>+z Stoppen van programma
CTRL-ALT-<Functietoets> Switch screen in GUI environment
ALT-F1 Switch screen in text environment
ALT-F7 Graphical environment

PTS

PTS Pseudo Terminal Sessie Staat in /dev/pts/0 Is gewoon een bestand en kan naar geschreven worden. Dit komt dan terecht op het desbetreffende scherm

Filesystem Info

Inode

Understanding UNIX / Linux filesystem Inodes The inode (index node) is a fundamental concept in the Linux filesystem. Each object in the filesystem is represented by an inode. But what are the objects? Let us try to understand it in simple words. Each and every file under Linux (and UNIX) has following attributes:

  • File type (executable, block special etc)
  • Permissions (read, write etc)
  • Owner
  • Group
  • File Size
  • File access, change and modification time (remember UNIX or Linux never stores file creation time, this is favorite question asked in UNIX/Linux sys admin job interview)
  • File deletion time
  • Number of links (soft/hard)
  • Extended attribute such as append only or no one can delete file including root user (immutability)
  • Access Control List (ACLs)

All the above information stored in an inode. In short the inode identifies the file and its attributes (as above) . Each inode is identified by a unique inode number within the file system. Inode is also know as index number.

How do I see file inode number?

$ ls -i /etc/passwd

You can also use stat command to find out inode number and its attribute:

$ stat /etc/passwd

Find and remove file using find command (necessary with special characters), type the command as follows:

$ find . -inum 782263 -exec rm -i {} \;

Additional info: A directory is nothing more than a table of the underlying files and a pointer to the inode information of this file. To “jump” to this inode table you need execute rights on the direcory. So if you want to open a file you'll also need execute rights on the directory.

Filesystem Commands

du --max-depth=1 -h -c
	Grootte weergeven van alle dirs 1 level diep, leesbaar en een totaal
df	Overzicht van vrije ruimte
	-h = Human readable
touch "bestandsnaam"
        Leeg bestand aanmaken
        Indien het bestand al bestaat worden alledrie de data bijgewekt (modify date, access date en change date)
file "bestand"
        Geeft het type bestand weer
stat "bestand"
        Geeft het type bestand, het inode nummer en alledrie de data weer (modify date, access date en change date)
ls      Simple file listing
ls -l   Long file listing
ls -t   File listing op wijzigingsdatum
ls -r   Omgekeerde filelisting
ls -a   Inclusief bestanden die beginnen met een . (zijn hidden voor het normale ls commando)
ls -l | wc -l
	wc = wordcount, -l betekent tel de regels, geeft dus de hoeveelheid
	regels in een directory.
ls [abc]
        Laat alle bestanden zien die een a en of een b en of een c bevatten
ls [!abc]
        Laat alle bestanden zien behalve de bestanden die een a, b, en of een c bevatten in de naam
ls [a-d]*
	Laat alle bestanden zien die beginnen met a,b,c of d
ls [ad]*
	Laat alle bestanden zien die beginnen met a of d
ls [ad][ae]*
	Laat alle bestanden zien die beginnen met a of d en als tweede letter
	een a of een e heeft.
ls [a-bA-B]*
	Laat alle bestanden zien die beginnen met a, A, b of B
ls [ab]?*
	Laat alle bestanden zien die beginnen met a of b en nog minimaal 1
	extra karakter heeft.
ls *[!a-zA-Z]
        Laat alle bestanden zien die niet eindigen op een letter
ln -s "brondirectory" "doeldirectory"
	Maakt een symbolic link voor de brondirectory op de doeldirectory.
	VB: ln -s \mnt\external \external
	Indien je nu in \external zit en je geeft "pwd" dan krijg je ook
	\external terug.
ln -s "existingfile" "linkfile"
        The same as with the directory. 
mv dffile.txt `date +%d%b%y%X`_dffile.txt
	Het bestand dffile.txt hernoemen naar <datumstring>_dffile.txt

Environment info

  • .profile
    • Aanpassen variabelen (moeten geexporteerd worden) en zaken als de prompt
    • ENV Speciale variabele, deze wordt gebruikt om een bestand aan te geven wat uitgevoerd wordt zodra de shell wordt gestart.
    • Hierin kunnen dan nog extra variabelen worden opgegeven, evenals aliases. Meestal is dit .bashrc en .kshrc
  • .dtprofile
    • Aanpassen grafische omgeving, DTSOURCEPROFILE moet op TRUE staan om ook de .profile in te lezen
  • .exrc
    • Wordt uitgevoerd zodra vi wordt opgestart.
    • Hierin kun je dus zaken als “set number” en “set showmode” inzetten
  • .hushlogin
    • Indien het lege bestans .hushlogin bestaat in je HOME dan krijg je niet de motd te zien

Variabelen info

Standaard variabelen (o.a.):
        PS1          Prompt
        PS2          Vervolg prompt
        HOME         Home directory
        PATH         Waar commando's te vinden zijn
set     Geeft de aanwezige variabelen
x=10    De waarde 10 toekennen aan de variabele x
        " " Hiermee kun je ook spaties in de waarde gebruiken, en $ en \ behouden hun shell interpretatie
        ' ' Hiermee kun je ook spaties in de waarde gebruiken, en alle speciale karakters verliezen hun shell interpretatie
                    (uitzondering hierop is de PS1 variabele)
echo ${var}tekst
        Zo kun je tekst achter de variabele zetten
x=$(command)
        Geeft de output van het commando aan de variabele x
        uitkomst=$(set|wc -l)
readonly var=waarde
        Deze variabele mag niet meer worden aangepast
unset var
        Verwijderd de variabele (werkt niet op readonly variabelen)
export var
        Exporteerd de variabele zodat deze ook aanwezig is/werkt in subshells

Regular Expressions

Tussen ''
.       Any single character
*       0,1 of meer van het voorgaande karakter
.*      0,1 of meer van een willekeurig karakter
[aA]    a of A
[a-f]   a t/m f
^a      Begint met a
a&      Eindigd op a
^a.*b$  Alles wat begint met een a en eindigd met een b
^$      Empty line
Combined with grep you can use regular expressions to filter out comments and empty lines out of config files. However, this should take you two regular expressions: grep -v '^&' file | grep -v '^#'. Using egrep allows you to do that in one go: egrep -v '^$|^#' file

Basis Commands

commando 
        & Programma in de achtergrond starten (output en errors komen nog steeds op het scherm)
        < input redirection
        > output redirection
        2> error redirection
        2>&1 Combine output and errors for redirection to a command or a file
        >> output redirection append
        | pipe, output van het ene commando wordt input van het andere commando (errors gaan nog steeds naar het scherm)
        ls -lR / >fs 2>&1          Output en errors gaan naar hetzelfde bestand (&1 geeft aan dat naar hetzelfde als de output moet gaan)
        command >2&1 | command2    Output en errors worden input van command2
tee     De input voor dit commando kan naar een bestand worden geschreven en stuurt de exacte input ook door als output.
command | tee file1 | command2
        De output van het command gaat dus zowel naar tee als naar command2
command ; command ; command
        Verschillende commando's op één regel plaatst
Sommige karakters hebben in de shell een bepaalde betekenis, zoals de $, *, (), [], {}, >, < , spatie, enter enz
        Deze shell interpretatie kun je uitschakelen door het karakter te escapen met een \ of door het geheel tussen enkele quotes te zetten.
        Met dubbele quotes schakel je de meeste karakters uit, behalve de $
        echo a*     Geeft alle bestanden in de directory beginnend met een a
        echo a\*    Geeft een echo van a*
        echo 'a*'   Geeft een echo van a*
        echo "a*"   Geeft een echo van a*
pwd     Print Working Directory
who     Zie wie er is ingelogd
who am i
        Zie wie jezelf bent met sessie informatie
whoami  Zie je userid
id      Zie je userid en je groep informatie
finger "userid"
        Krijg meer informatie over de desbetreffende gebruiker
more "bestand"
        Bestand zien
            <ENTER> : volgende regel
            <SPACE> : volgende pagina
            b       : vorige pagina
            q       : quit
cat "bestand"
        Bestand laten zien op scherm
        -vet Inclusief non-displayable karakters zoals <ENTER>
echo "string"
        String afdrukken op scherm
cut -f"n" -d";"
        Knip kolom n waarbij ; de delimiter is
        -f1-3 Knip kolom 1-3
        -f2,4 Knip kolom 2 en 4
        -f9-  Knip kolom 9 t/m het einde
su	Switch user (default root)
	- (ook de werkomgeving van de gebruiker laden)
sudo	Een enkel commando uitvoeren als root, je moet hiervoor in de sudoers
	file staan en je authenticeren als jezelf, niet als root.
man "commando"
	Uitleg van een commando geven
	-k "keyword" Zoeken in man pages
.tar.gz	Uncompress met gunzip "bestandsnaam"
	Uitpakken met tar xf "bestandsnaam"
	In 1 keer tar xzf "bestandsnaam"
	Bestanden ergens anders plaatsen met tar xzf "bestandsnaam" -C "directory"

Remove directory from within a tar ball:
 tar --delete -f NB7601RH.tar 'NetBackup_7.6.0.1_CLIENTS2/NBClients/anb/Clients/usr/openv/netbackup/client/Linux/Debian2.6.18'


.tar.bz2
	Uncompress met bunzip2 "bestandsnaam"
	In 1 keer uitpakken met xjf "bestandsnaam"
mail	Ingelogd als user krijg je je ontvangen mail te zien (staat ook in /var/spool/mail/<usernaam>
	Nadat je het hebt gelezen wordt het verplaatst naar de homedirectory/mbox
        cat /proc/cpuinfo | mail -s "TESTMAIL VANMEZELF" ogd@sjoerd.linux.gevorderden.cursus.lan
	     Alles wat wordt gepiped naar mail is body => wordt met een subject "TESTMAIL VANMEZELF" verstuurd
expr    Rekencommando
        expr 2 + 2 Geeft een output van 4
        expr 2 /* 2 Geeft een output van 4 (ster moet escaped worden)
        som=$(expr $a - 1)
            Geeft aan de variabele de uitkomst van het verhogen van de variabele a met het getal 1
xargs command {}
        Elke regel uit de input wordt een argument {} voor het commando
        -t laten zien
        -I{} Op elke plek waar {} staat de input neerzetten
        cat filelist | xargs -t rm
        find . -type f | grep 'abc'       Geeft alle bestanden die abc in de naam hebben
        find . -type f | xargs grep 'abc' Geeft alle betanden die abc in de inhoud hebben (bestanden worden als argumenten gegeven aan grep)
        ls | xargs -t -I{} mv {} {}.old   Hernoemd alle bestanden

Netwerk Commands

hostname
        Hostname + domain
hostname -s
        Hostname zonder domain
scp "bron" "doel"
	scp servernaam:/home/file /doelbestand
scp -r  Hiermee kan je directories kopiëren. 
ssh "usernaam"@"ipadres"
	ssh root@10.0.0.1
	ssh -l "usernaam" "ipadres"
	ssh "ipadres"
	Hiermee wordt er geprobeerd in te loggen met de user waarmee je op dat
	moment ingelogd bent.
/sbin/ifconfig
	ifconfig opvragen onder normale gebruiker (mag gewoonlijk alleen als
	root). 
	Indien je wijzigingen maakt met ifconfig zijn deze slechts tijdelijk.
	Permanente wijzigingen dien je te maken in ifcfg-eth0, lokatie is
	distro afhankelijk
netstat -a
        Alle openstaande poorten
        -n Numeriek
        -r Route tabel
        -p Inclusief processen
netstat -nap | grep :389
        Zoeken op openstaande poort 389 met het bijbehorende proces
netstat -rn 
        Print de numerieke routetabel
last    Laat de afgelopen paar logins zien
        -20 De laatste 20 regels
        root De logins van root
        ftp De ftp sessies

Proces commands

top	Overzicht van processen
	c Expand processen
	1 alle processoren apart
	s verversing afstellen
	P sorteren op processor utilization
	M sorteren op memory utilization
ps -e	Alle processen die draaien
ps -f   Geeft volledige info van de processen, inclusief parent pid (ppid)
ps -ef	Alle processen die draaien, met volledige info, met uitzondering van kernel processen
pd -Af  Alle processen die draaien, met volledige info
ps -u "userid"
        Geeft alle processen van de opgegeven user
commando &
        Draait het opgegeven commando in de achtergrond
jobs    Geeft alle processen van de huidige sessie die in de achtergrond draaien
jobs -l Geeft de jobnummers en de pids (de job met + is de primaire job)
<CTRL>+z 
        Stopt het programma in de voorgrond, hierbij krijgt het een jobnummer
bg %jobnr
        Plaatst het programma met het opgegeven jobnr in de achtergrond (kan ook met PID nummer)
fg %jobnr
        Plaatst het programma met het opgegeven jobnr in de voorgrond (kan ook met PID nummer)
nohup commando &
        Plaatst het programma zodanig in de achtergrond dat het ook blijft draaien indien de sessie wordt gesloten
kill -s PID/%jobnr
        Stuurt een kill signal naar het programma met het opgegeven PID
kill -l Geeft een overzicht van beschikbare signals
        9 sterkste signaal

Zoek Commands

grep -r "regular expression" "input"
	input mag vanuit een ander commando zijn, file(s) of een directorie
        -r recursief (indien je binnen bestanden zoekt)
	-i Case insensitive
	-v Geef de regels die niet matchen
	-l Geef alleen de filenamen die matchen
	-w zoek op het complete woord
        ls -l | grep '^d'
	    Geeft alle directories
	grep -rlw test .
             Zoekt in alle bestanden in je huidige directory en dieper naar het exacte woord test en laat alleen de bestandsnamen zien
find "waar" "wat" "waarop"
        waar = directory
	    / vanaf root
	    . vanaf huidige diretory
        wat en waarom type en string
            -name abc   op naam
            -type f     op files
                  d     op directories
            -user id    op bestanden van userid
            -size +2    Groter dan 2 blocks
            -size -2    Kleinder dan 2 blocks
            -size 2     Gelijk aan 2 blocks
            Deze opties mag je combineren:
            -type f -name 'a*' Zoeken op bestanden die beginnen met a
            -type d -o -name 'a*' Of directories of bestanden die beginnen met a
find . -name 'a*' -exec ls -l {} \;
        {} De gevonden waarde
        Zoek alle bestanden die beginnen met een a en voer er het commando mee uit wat achter exec staat. Binnen de {} komt de gevonden waarde te staan.
        Meer voorbeelden:
            find /var/news -type f -exec chmod o+r {} \;
                Geef leesrechten aan other voor alle bestanden die in /var/news staan.
            find /tmp -type f -exec mv {} {}.old \;
                Hernoem alle bestanden in /tmp naar bestandsnaam.old
        Indien je -exec vervangt met -ok vraagt hij voor elke bewerking een bevestiging
find is altijd recursief
find 'a*'
        Geeft bestanden die met een a beginnen
grep 'a.*'
        Geeft bestanden waarin de naam een a bevat

Hardware Commands

cat /proc/cpuinfo
	Informatie weergeven van alle processoren
mount /dev/sdb5 /mnt/external -o uid=500
	Het sdb5 device mounten waarbij je gelijk gebruiker met het uid van 500 toegang geeft
mount idm.iso /mnt/iso/ -o ro,loop=/dev/loop0 
	Het mounten van een iso
fdisk -l /dev/sdb
	Partitionering zien van de harde schijf /dev/sdb

Logging Commands

tail -f "logfile"
	Verversen van log file
tail +5 Bestand laten zien vanaf regel 5
tail -2 Laatste 2 regels laten zien van een bestand (standaard 10)
head -8 Eerste 8 regels zien van een bestand (standaard 10)
cat "logfile" | grep SjoerdH | cut -f3 -d:
	Van de regel met SjoerdH erin het derde veld pakken met als delimiter
	":"
dmesg	Kernel messages
        /var/log/messages

Resque Tools

qtpart Grafische partitionering

PackageManagers

rpm -i	"pakketnaam"
	Installeer rpm pakket met de naam "pakketnaam".
	-ivh Verbose output met printed hash marks (altijd aan te raden)
rpm -qa Geef geinstalleerde pakketten weer (kun je doorpijpen naar grep).
rpm -ql "pakketnaam"
	Geeft alle bestanden die horen bij "pakketnaam".
rpm -qf "bestandsnaam"
	Geeft het pakket wat hoort bij een specifiek bestand.
yum install "pakketnaam"
yum search "string"
yum remove "pakketnaam"
yast2 -i "pakketnaam"
        Installeert pakketnaam in een grafische omgeving
yast -i "pakketnaam"
        Installeert pakketnaam in een command-line mode 

VI

i	Insert text voor de cursor
a 	Append text na de cursor
I       Insert text aan het begin van de regel
A 	Append text aan het eind van de regel
r	Replace karakter
R	Replace text
x	Verwijder karakter
5x	Verwijder 5 karakters
dd	Huidige regel verwijderen
d"movecommando"
        Verwijderd t/m je move, dus dw verwijderd het volgende woord
10dd	10 regels verwijderen
2,4dd   Regels 2 t/m 4 verwijderen
10yy	10 regels kopieren
	p 
	Deze regels vervolgens plakken (geld ook voor verwijderde tekst)
u	Undo laatste wijziging
o	Nieuwe regel onder de huidige en insert
O 	Nieuwe regel boven de huidige en insert
/"string"
	Zoeken naar opgegeven string naar beneden
?"string"
        Zoeken naar opgegeven string omhoog
n 	Zoek naar de volgende hit in dezelfde richting
N       Zoek naar de volgende hit in tegenovergestelde richting
h       Ga 1 positie naar links
j       Ga 1 positie naar beneden
k       Ga 1 positie naar boven
l       Ga 1 positie naar rechts
<Ctrl>+f
        scroll 1 scherm verder
<Ctrl>+u 	
        scroll een half scherm terug
<Ctrl>+d
        scroll een half scherm verder
<Ctrl>+b
        scroll 1 scherm terug
z,      Plaatst de huidige regel bovenaan
z.      Plaatst de huidige regel in het midden
z- 	Plaatst de huidige regel onderaan
w       Ga naar het volgende woord
b       Ga naar het volgende woord
$       Ga naar het einde van de regel
0 	Ga neer het begin van de regel
G 	Ga naar de laatste regel van het bestand
1G      Ga naar regel 1
206G    Ga naar regel 206
fx      Ga naar de eerste "x" op de regel
;       Ga naar de volgende "x" op de regel
:w      Bestand opslaan
:q      Bestand sluiten
:wq     Bestand opslaan en sluiten
:wq!    Bestand opslaan, sluiten en override evt fouten (zoals readonly)
:X      Bestand encrypteren
:set number
	Regelnummers verkrijgen
:set showmode
        Input mode en commando mode zien
:!"command"
        Even op de shell een commando uitvoeren
:r "file"
        Voegt een bestand in onder je huidige regel
        4r Voegt een bestand in onder regel 4
        0r Voegt een bestand in bovenaan je document
POWEREXAMPLES:
:%s/string/string/
        :%s  Search and replace (substitute) in het complete document
        Eerste /string/ is de tekst die vervangen gaat worden door de tekst in de tweede /string/
:g/string/d
        g Commando geldt voor het complete document (global)
        /string/ is de tekst waarop gezocht wordt
        d Verwijder de regel waar de tekst in voorkomt
:10,20g/string/string/gc
        10,20g Veranderingen tussen regel 10 en 20
        gc Niet alleen de eerste hit op de regel maar ook anderen, en bevestiging vragen
:%s/string.*$/&^Muserpassword: ogdogd/
        .*$ Matcht je search pattern plus alles wat verder nog op de regel staat
        & Dit is een speciaal teken in je replace string wat gelijk is aan het gematchte stuk tekst.
        Gevolg: Hij laat de gematchte tekst netjes staan waar het stond, dus alles wat achter de & komt wordt ingevoegd na het gematchte stuk tekst (je search pattern plus de rest van de regel)
        ^M Nieuwe regel, deze krijg je overigens door eerst <CTRL>+V in te tikken en daarna <CTRL>+M

Rechten en Permissies

- --- --- ---
-	Type bestand
	- of leeg is een normaal bestand
	d directory
	l link
---	Owner/User
---	Groups
---	Others
rwx	read, write, execute
	Execute op een directory betekent dat je hem listen zonder dat je de
	bestandsnaam weet
	Read = 4
	Write = 2
	Execute = 1
	Read en Execute: 5
	Read, Write en Execute: 7
	Read en Write: 4
chmod	Rechten aanpassen
	-R Recursief
chmod <777> "bestandsnaam"
	Rechten op "bestandsnaam" aanpassen naar <777>
chmod u+r "bestandsnaam"
	Rechten van de user uitbreiden met leesrechten
	u = user
	g = group
	o = others
	a = all
chown	Change ownership van een bestand
chown root:admins "bestand"
	Verander de eigenaar naar root en de groep naar admins
	-R inclusief alle onderliggende bestanden in het geval van een
	directory
Default rechten op een nieuw bestand zijn 666 en op een directory is 777. Daar wordt de umask vanaf gehaald. Deze is standaard 022.
umask   Geeft de umask waarde
umask "getal"
        Stelt een nieuwe umask waarde in
Bij het maken van een nieuw bestand of directory wordt de primaire groep gebruikt als groep eigenaar van het bestand.
newgrp "groep"
        Stelt de gekozen groep in als nieuwe primaire groep
rwsrwsrwt
        s Tijdens het uitvoeren van een programma wordt dit gedaan met de rechten van de owner, of van de groep (bijvoorbeeld bij programma's die van de user bin zijn).
        t Bestanden kunnen alleen verwijderd worden door de eigenaar (bijvoorbeeld in temp)
        S De owner zelf heeft de rechten niet
        De sst worden ook weergegeven met getallen, namelijk 421, en deze wordt ervoor gezet.
            7777: rwsrwsrwt
            5777: rwsrwxrwt

Scripts

Script run possibilities

Je hebt drie manieren om scripts te draaien:

  • bash script
    • Script draait in subshell en leesrechten zijn voldoende
  • (./)script
    • Script draait in subshell en execute rechten zijn benodigd
  • . (./)script
    • Script draait in huidige shell en leesrechten zijn voldoende (wordt gebruikt om variabelen te exporteren)

Overige opmerkingen

read Wacht op input gevolgd door een <ENTER> Commentaar in scripts zet je met #, mag ook aan het einde van een regel waar al code staat Bash #!/bin/bash

Script examples

Cleanup script

# Set var to directory which needs to be cleaned up
LOGDIR=/var/log/app/logs

cd $LOGDIR
find . -type f -ctime +28 -name 'applogfile.log*' -exec rm {} \;
find . -type f -ctime +28 -name 'app2logfile.log*' -exec rm {} \;

Note: this cleanup script removes files older then 4 weeks and have a name that starts with applogfile.log or app2logfile.log.

Overige opmerkingen

CUPS	http://localhost:631 - standaard webinterface

PORTS:  Je hebt root rechten nodig om een poort onder de 1024 toe te kennen.
You could leave a comment if you were logged in.
linuxtips.txt · Last modified: 2021/09/24 00:24 (external edit)