Unix tricks
mmb.pcb.ub.es
mmb.pcb.ub.es
'!!:n' selects the nth argument of the last command, and '!$' the last arg
A lot of people know about "!$" (which is shorthand for !!:$), but that's just the tip of Bash's history expansion. I use these things all the time. One of my favorite keystroke savers is adding :h, the head modifier, to !$. For example: $ cp file.txt /some/annoyingly/deep/target/directory/other.txt
$ cd !$:h
$ pwd # => /some/annoyingly/deep/target/directory
Once you understand how each component works it's easier to put them together into new (to you) combinations. For example, once you know that !$ is shorthand for !!:$, it's not a huge leap to reason out that you can use !-2:$ to get the last argument to the 2nd-to-last command. Or !ls:$ for the last arg to the most recent `ls` command.I also prefer to do substitution with the :s modifier rather than ^ as suggested at the link, for consistency's sake:
$ echo "foo bar"
foo bar
$ echo !!:s/bar/baz
foo baz
$ echo !?bar?:s/foo/qux
qux bar
Relevant Bash manual pages:http://www.gnu.org/software/bash/manual/html_node/Event-Desi...
http://www.gnu.org/software/bash/manual/html_node/Word-Desig...
http://www.gnu.org/software/bash/manual/html_node/Modifiers....
$ cp file.txt /some/annoyingly/deep/target/directory/other.txt
$ cd !$ (No such file or directory)
(up arrow and then backspace to directory)
$ cp file.txt /some/annoyingly/deep/target/directory/other.txt
$ cd then press Alt + .
$ pwd # => /some/annoyingly/deep/target/directory $ echo foo/bar
foo/bar
$ echo !$ !$:h
foo/bar fooIn comparison. !$:h understands its task at a higher level. And thanks to key rollover, typing different characters, like !$:h, is quicker than tapping away at . until visual feedback, which may lag, tells me I've done enough.
$if Bash
Space: magic-space
$endif
Basically does the same thing as :p, but after a space instead of enter.Edit: fixed formatting.
$ echo a b c d
a b c d
$ echo !!:2:p
echo b
$ echo !!:2
-bash: :2: bad word specifier # there was only 1 argument in last command
However: $ echo a b c d
a b c d
$ echo !!:2:p
echo b
$
<up-arrow pressed once will give the following prompt>
$ echo b shopt -s histverify
to show the expanded command before executing it. Then just enter. I never get these right the first time. $ echo "foo foo"
foo foo
$ echo !!:s/foo/bar
echo echo "bar foo"
echo bar foo
$ echo "foo foo"
foo foo
$ echo !!:gs/foo/bar
echo echo "bar bar"
echo bar bar $ !!
runs the previous command.This is especially useful:
$ !!
$ sudo !!2) htop is a cpu and memory hog -- every time I've used it I noticed it takes 6+% CPU time
3) there's an awk trick to do the `sort | uniq` recommendation that works on 10+GB files (single pass):
awk '!x[$0]++'
4) Passwordless keys are dangerous -- use ssh-agent to save the password of the keys1. I prefer 'psgrep' because it covers 99% of my use cases for pgrep (ps axuf | grep $NAME)
2. htop is very nice, come on! Would not let it running on the background for hours, but it's nicer than top
3. Note taken, thanks!
4. Is ssh-agent really safer than using passwordless keys? Just asking, I'm curious
2. In my experience on Debian (granted this was in 2010), there is a noticeable performance difference between `htop` and `top`.
4. ssh-agent stores the password in memory and is erased on reboot. OTOH If you use a passwordless key file, anyone can use it if they have the key.
% ps auwx | grep '[f]oo' | awk '{ print $2; }'A passwordless key gives anyone with acces to that file, access to the login associated with it. If that file is inadvertently exposed (oops, checked it into github...), any machine you have a login on must be considered compromised.
For example if you login remotely to a machine, and want to access a git repository on another:
$ eval `ssh-agent -s`
$ ssh-add ~/.ssh/id_<yourkey>
$ ssh -A <firstserver>
you@firstserver$ git clone git+ssh://<secondserver>/path/to/repositoryAgent forwarding should be enabled with caution. Users with the ability to bypass file permissions on the remote host (for the agent's UNIX-domain socket) can access the local agent through the forwarded connection. An attacker cannot obtain key material from the agent, however they can perform operations on the keys that enable them to authenticate using the identities loaded into the agent.
Consider using a dedicated key for each of those circumstances, set sane defaults in your ~/.ssh/config on all machines, and be very careful about what ends up in any of your ~/.ssh/known_hosts files, as they provide a road map to other destinations.
I tried it on a 1U server with 24GB ram a few years ago and found that the sort was thrashing at the 10GB file size while AWK handled it easily
Awk may still be better for uniquification.
For files with relatively few duplicates it's going to be a lot slower than sort | uniq.
Trying it on a 128MB file (nowhere near enough time to test a 10GB file) filled with lines of 7 random upper case characters[1] (so hardly any duplicates):-
$ wc -l x.out
16777216 x.out
$ time ( sort x.out | uniq ) | wc -l
16759719
real 0m17.982s
user 0m42.575s
sys 0m0.876s
$ time ( sort -u x.out ) | wc -l
16759719
real 0m20.582s
user 0m43.775s
sys 0m0.688s
Not much difference between "sort | uniq" and "sort -u".As for the awk method:-
$ time awk '!x[$0]++' x.out | wc -l
has been running for more than 20 minutes and still hasn't returned. For that 128MB file the awk process is also using 650MB of memory (according to ps). Will check up on it later (have to go out now).This Linux machine has ~16GB of memory so the file was going to be completed cached in memory before the first test. All things considered equal the awk method will be roughly O(n) (e.g. linear against file size) and sort/uniq will be O(n log n). So, theoretically, the awk method will eventually surpass the sort method because it's having to do less work (it's only checking for a previously seen key rather than sorting the entire file) but I'm not sure the crossover will be anywhere useful if the file doesn't contain many duplicates.
Repeating it for a file containing lots of duplicates (same 128MB file size but contents are only the 7 letter words consisting of A or B, so only 128 possible entries):-
$ time awk '!x[$0]++' y.out | wc -l
128
real 0m1.207s
user 0m1.192s
sys 0m0.016s
$ time ( sort y.out | uniq ) | wc -l
128
real 0m14.320s
user 0m31.414s
sys 0m0.428s
$ time ( sort -u y.out | uniq ) | wc -l
128
real 0m12.638s
user 0m30.366s
sys 0m0.188s
Notice that "sort -u" doesn't do anything clever for files with lots of duplicates.So awk is much faster for files with lots of duplicates. No great surprises. When I get a chance I'll repeat it for a 1GB file and a 10GB file (with lots of duplicates otherwise the awk version will take far too long).
1. Example contents:-
EPQKHPH DLJCROB WICVGQY MHWTPSR HMPNECN
$ time awk '!x[$0]++' x.out | wc -l
16759719
real 64m41.089s
user 64m31.970s
sys 0m3.136s
Peak memory usage (given that it was a 128MB input file) was (pid, rss, vsz, comm): 8972 1239744 1246488 \_ awk
So > 1GB for a 128MB input file.Technically that's true, but the result of a cryptographic hash like SHA-256 is (practically) guaranteed to be unique. Depending on the average length of an input line and how many of the lines are unique, storing only the SHA-256 hash value could take far less memory than storing the input lines along with a non-cryptographic 32-bit hash value.
Typical undetected bit error rates on hard disks are one error per 10¹⁴ bits, which is about 2⁴⁷. If your lines are about 64 characters long, you'll have an undetected bit error roughly every 2^(47-6-3) = 2³⁸ lines. SHA-256 will give you an undetected hash collision roughly every 2²⁵⁵ lines. That is, for every 2²¹⁷ disk errors, SHA-256 will introduce an additional error. If you're hashing a billion lines a second (2³⁰) then that will be 2^(217-30) = 2¹⁸⁷ seconds, while the disk is giving you an undetected bit error every minute or so. A year is about 2²⁵ seconds, so that's about 2¹⁶² years, about 10⁴⁹. By comparison, stars will cease to form in about 10¹⁴ years, all planets will be flung from their orbits around the burned-out remnants of stars by random gravitational perturbations in about 10¹⁵ years, the stellar remnants will cease to form cold, dark galaxies in about 10²⁰ years, and all protons will have decayed in about 10⁴⁰ years.
And if you somehow manage to keep running uniq on your very large file at a billion lines a second, in a mere 500 times the amount of time from the universe's birth to the time when nothing is left of matter but black holes, SHA-256 will have produced your first random false collision.
1. Use zsh, not bash. AUTO_PUSHD, CORRECT_ALL and tons of other options make some tricks redundant. Also, the zle M-n and M-p are more useful than C-r imo.
2. Use tmux, not screen.
3. Use z (https://github.com/rupa/z), not j.py.
4. Use cron, not at. Or even systemd timer units, if you're so inclined.
5. Use public-key authentication and keychain, not password-based SSH.
6. Don't send emails from command-line naively; you have no control over the headers. Use git-send-email or similar.
7. Consider using something slightly more sophisticated than Python's SimpleHTTPServer to share files/ folders. One example: woof (http://www.home.unix-ag.org/simon/woof.html)
Sad, but I find this is generally the case in extremely large enterprises where there is a mix of AIX, HPUX, Linux and Solaris being used due to years of weird procurement decisions. Sigh.
I've also invested enough time in learning bash over the years that zsh is not a net-win for me. I've switched to using it on some systems but I seldom use more than what's available in bash. I would switch back to bash on these systems for consistency, but I feel like I've already sunk too much time in to this experiment of using zsh.
don't be a zsh/tmux hipster; there's nothing wrong with "good enough". this lesson has played out several times as businesses / software with arguably better execution / implementation loses out to existing players that have been around a while.
Edit: though, if you're relatively new and haven't been using bash/screen/whatever for decades, I don't think anybody would call you a hipster for using zsh/tmux instead of bash/screen. The marginal utility of learning tmux or zsh is much higher for somebody who hasn't already used other stuff forever.
Edit: also, @climagic: https://twitter.com/climagic
Second edit: I'm enhancing the file with these comments, so if there are any inconsistencies between the txt and a commenter, it's my fault.
It substitutes the last argument in the previous command into the current one.
For example:
$ ls /some/long/path/somewhere/looking/around/
<output>
$ cd !$
cd /some/long/path/somewhere/looking/around/Also, check it:
$ cd /happily/tabbing/out/some/really/deep/path/ooh/dear/maybe/its/java/WAIT_A.file
bash:> 'WAIT-A.file' is not a directory
$ nano $_ (opens file)
Yes, I know about iTerm. I don’t want it.
$ echo a b c d
a b c d
$ echo # pressing <Alt+<2>+.> here inserts 'c', not 'b'. 'tar cz folder/ | ssh server "tar xz"'
Can be pulled off with two flags to scp - and you get to see progress as a benefit! scp -Cr folder server:dest/scp won't copy certain file types correctly. Rsync really is better here, and not just because of that.
I'm not aware of any attributes that tar doesn't preserve.
Also, I find that if I'm going to copy the data once, I'm often going to copy it twice, or which to get a more up to date version of it at a later time. Rsync clearly wins in these cases.
Finally, from the compress flag on rsync: Note that this option typically achieves better compression ratios than can be achieved by using a compressing remote shell or a compressing transport because it takes advantage of the implicit information in the matching data blocks that are not explicitly sent over the connection.
Remember: Rsync trades CPU and disk i/o (lots of disk i/o) for network bandwidth.
In the pathological case "thousands of tiny files over a fast network" it can easily be orders of magnitude slower than a straight tar.
You will also get better compression with tar (or rsync), as it is compressing the files directly, and not just the ssh stream (-C is just passed on to ssh).
I did the tests years ago, but a quick google found someone who tried to test the various combinations: http://www.spikelab.org/transfer-largedata-scp-tarssh-tarnc-...
On the receiving machine, in its destination directory:
nc -l 6789 | tar xvf -
And on the sending machine, from its source directory: tar cvf - . | nc receiving-machine 6789
netcat varies a bit from distro to distro, so you may need to adjust these command lines a bit to get it to work.If it doesn't know how many bytes there will be, it just gives you a "throbber" (which is better than nothing, though).
cat file | pv | nc ...
and gzip < file | pv | nc ...
and so forth will result in a throbber as it can't query the pipe for a length.If you demoggify the first example to:
pv file | nc ...
you get a progress bar on the sending end without manually specifying a size.Even without a proper % progress bar, the display can be useful as you can at least see the total sent so far (so if you know the approximate final size you can judge completeness in your head) and the current rate (so you can see it is progressing as expected (so you get some indication of a problem such as an unexpectedly slow network connection, other than it taking too long)).
ProxyCommand ssh -T host1 'nc %h %p'
you can use ProxyCommand ssh -W %h:%p host1
which uses ssh itself and therefor also works on machines where netcat isn't installed.To my surprise, this also works with git:
git checkout - # to checkout the previous branchctrl-z - stops a program
bg - sends the stopped program to the background
fg - gets the program back to the foreground (interactive mode)
very useful in editor sessions or when you want to get rid of the endless download/scp that is blocking your terminal
$ some_command
^Z (hit control z)
$ some_command_2
^Z (hit control z)
$ jobs
[1]- Stopped some_command
[2]+ Stopped some_command_2
$ kill %1
$ jobs
[1]- Terminated: 15 some_command
[2]+ Stopped some_command_2fork() { (setsid "$@" &); }
in myzshrc, and then start stuff with :
fork firefox
$ alias b='echo -e "\a"'
$ long_running_thing
^Z
$ fg ; b
[long_running_thing resumes]
Then when the job completes, the terminal bell will ring and my window manager will get my attention. history | commandlinthttps://news.ycombinator.com/item?id=5022457
https://news.ycombinator.com/item?id=4481234
A pretty good thread on Reddit:
http://www.reddit.com/r/linux/comments/mi80x/give_me_that_on...
Edit: see https://news.ycombinator.com/item?id=3257393 for a discussion of the above thread.
While we're at it, consider using weborf [1] as an alternative to Python's SimpleHTTPServer for simple file sharing. I found it able to saturate a gigabit ethernet connection when hosted on a Core 2 Duo ULV laptop with an SSD.
[1] See http://galileo.dmi.unict.it/wiki/weborf/doku.php?id=start. It's available from the official repos in Debian and Ubuntu with
sudo apt-get install weborf
Invoking it is dead simple: weborf -b ~/dir-to-shareI will have to look at weborf. I have always wished debian packaged publicfile, similar to djbdns or even dbndns. As it is I am still looking for a "djbdns-like http server" that is apt-get installable and actively maintained.
I will never understand why gnome-user-share depends on apache...
# Bind the up arrow to history search, instead of history step
"\e[A": history-search-backward
"\e[B": history-search-forward
No more "^rls" to search for ls in your bash history; just type "ls" and start hitting the up arrow.I got tired of sshing into a new box and half the things I'd type wouldn't work properly until I remembered to copy my settings files over, which seemed more trouble than it was worth for a short-lived s3 instance.
That's why I was excited to discover ctrl-r. It's a built-in method of searching history that I can remember and it'll work everywhere.
I've got a public repo of my dotfiles, so the first thing I typically do is "git clone git@github.com:pavellishin/dotfiles.git && cd dotfiles && ./install.sh"
After that, I launch tmux, and it's all hunky dory.
Thanks for giving me the push to do so. I think I'll take your suggestion but put the command on a site somewhere so I can simply 'curl https://foo.bar/configs | bash'
set editing-mode vi
(or set editing-mode emacs) because any application that uses readline gets to use those settings. So for example you get command line editing in various command line apps. bash uses readline, so you'll get that. The python repl will give command line editing with .inputrc set as above.
$ apt-rdepends -r libreadline6 |egrep -ve "^ " |wc -l
8995
psql (postgresql) and mysql (mysql) are really handy with command line editing."'ctrl-x ctrl-e' opens an editor to work with long or complex command lines"
If you've set -o vi, or set editing-mode vi in .inputrc, then on a command line type:
esc-v
(Escape key to get out of insert mode, then the 'v' key) That will open a full vim session for editing your complex command line. :wq
exits vim and gives your command to bash to execute.Hung SSH session (such as wifi out of range)?
Type Return-Tilde-Period
you@somehost:~$ ssh otherhost
you@otherhost:~$ some_command
If you hit ^Z right now, it will tell the shell on otherhost to stop some_command and give you the shell prompt on otherhost back.If instead you wanted to stop the ssh process and get the shell prompt on somehost, hit Tilde ^Z (you don't have to hit a new Return, but ssh only notices these escape sequences after a Return).
Also if you use ControlMaster and have a few xterms open all with sshs to otherhost, and then you exit the first ssh you happened to have open, it will seem to hang and not give you your prompt back. What's happening is that that ssh process is the "control master" and it's still open because you've got other sshs to the same host open. Hit Tilde & to background the ssh process and get your terminal back.
Yes, you could also hit Tilde ^Z and then 'bg' the ssh process.
or just use tmux
'find . -type d -exec chmod g+x {} \;'
If you happen to have a malicious directory named (without double quotes): ".;sudo rm -rf /"
You'd be stuffed.It's better practice to use the '-print0' flag of find(1) and pipe the result into xargs(1) with the '-0' flag set. For safety, it's best to also use '-r #' for expected number of arguments, '-n' to stop xargs from running without arguments, and "-J %" so you can use quoting.
find . -type d -print0 | xargs -0 -n -r 1 -J % chmod g+x "%"
I believe some on implementations '-n' is unnecessary when '-r #' is
specified, but on other implementations it's is the maximum.EDIT: thanks for the vim tip on for finding spelling mistakes!
$ mkdir '; echo woops'
$ find . -type d -exec echo {} ';'
.
./; echo woops
As you can see 'woops' is never echoed.EDIT: The reason being the shell is never involved in this process, and the shell is what is responsible for splitting commands on semicolons/newlines.
FWIW, your `find -print0`/`xargs -0` is not POSIX.
Also, it seems I failed to be clear; I'm probably too tired I suppose.
My point was there is plenty of ancient and buggy code out there. It could be "most", or even "many" modern unix variants have fixed a lot of the old bugs in find(1), but if you don't have the luxury of working on a current system, and your not allowed to upgrade it, then plenty bad things can happen due to invoking a shell, handling space, quote, and delimiter characters, and so forth.
reference:
$ uname -a
OpenBSD alien.foo.test 5.1 GENERIC.MP#207 amd64
setup: $ mkdir test
$ cd test
$ touch file1
$ touch file2
$ touch file3
$ mkdir ';ls'
bad: $ find . -type d -exec sh -c {} \;
sh: ./: cannot execute - Is a directory
;ls file1 file2 file3 test.sh
better: $ find . -type d -exec sh -ec {} \;
sh: ./: cannot execute - Is a directory
also bad: $ find . -type d -print0 | xargs -0 -r -n 1 -J % sh -c "%"
sh: ./: cannot execute - Is a directory
;ls file1 file2 file3 test.sh
better: $ find . -type d -print0 | xargs -0 -r -n 1 -x -J % sh -ec "%"
sh: ./: cannot execute - Is a directory
better; $ find . -type d -print0 | xargs -0 -r -J % sh -c "%"
best: $ find . -type d -print0 | xargs -0 -r -J % sh -ec "%"
POSIX is all great and wonderful in theory, but in practice it's no
different than the bogus Java "write once, run anywhere" claim. If a
system or utility claims to be POSIX compliant, then you're probably
close, but you'll still need to do testing and debugging.At least some of the issues with find/xargs are mentioned in the following wikipedia article. It's probably more clear than I am right now.
Your original argument was that given:
find . -type d -exec chmod g+x {} ';'
It is possible to force code execution of arbitrary commands given a carefully crafted directory name. The key difference in this case is that the shell is not involved _at all_. I challenge you to find an implementation of `find` that is broken in this way.As a side note, it is even possible to involve the shell in the picture in a safe way with `find`, without the use of `xargs` (and thus avoid the overhead of setting up a pipeline):
find . -type d -exec sh -c 'chmod g+x "$1"' _ {} ';'
(my contrived example is quite poor, though, since it does nothing but introduce unnecessary shell overhead)Modern (POSIX > 2001?) `find`'s support `-exec {} +` which further reduces the number of reasons to invoke `xargs`:
find . -type d -exec sh -c '
for x; do
do_foo "$x"
do_bar "$x"
do_baz "$x"
done
' _ {} +
(example above shows how to make proper use of this feature with an explicit shell invocation) find . -type d -exec chmod g+x {} \;'
you can usually use chmod -R g+X .
which gives additionally the group execute permission to files which have already user/everyone execute permission.More details would be nice.
Other than that, SMB allows for permissions and a bunch of other features. It is, basically, a more modern and robust protocol. Does NFS shine for some use cases? Indeed. Would it be the first choice for most ones? Nope.
Disclaimer: my sysadmin skills are not so great, I'm talking as a user
http://tldp.org/HOWTO/NFS-HOWTO/client.html
Soft mounts report errors immediately, hard mounts hang.
And for permissions, NFS provides everything under the sun that you could possibly need via ACLs. NFSv4 is a very modern protocol, much as SMBv2 is (not SMB though, it's awful).
Linux has had NFSv4 for what, 6 years now, at least, and even v2 and v3 had some limited ACL support?
It's a mount option on the client, not the server, so maybe you can change it yourself.
If you use any NAS device with a weak CPU and you have a choice of CIFS or NFS, the NFS transfer rates are normally 25% faster and the load is much less on the server.
And fwiw, if there's some sort of error with the mount, the terminal lets me know right away.
My only evidence is anecdotal. Back in ~1998 we had Samba running on our small Linux file server using Windows NT desktops via 10mbit Ethernet. It was dog slow, not just for browsing but on sequential things like file transfer. We installed NFS mounts on the same box, and it turned out to be lightning fast. I don't remember just how fast, but it made everyone go "wow".
Nowadays, with NFS over fast 100mbps or gigabit Ethernet the latency difference probably is not significant enough to make a difference. I prefer NFS just because its more Unixy.
2) Samba is single threaded, performance will suffer serving SMB from a Linux machine. For this reason it would be better to serve SMB from a Windows machine.
3) Using a foreign protocol between homogenous computers when the native protocol will do is non-ideal. NFS is the right thing when sharing filesystems from Linux to Linux.
"screen -X -S minecraftserver -p 0 -X stuff "say test $(printf '\r')"Either way, enjoy!
I discovered help <builtin> some months ago, and that was a great boon really. Like help "test" so I didn't have to go the rather large bash man page.
Here is a little shellscript for displaying a man page on Mac Os X (gman). (If you then click on on of the links on the man-page, it may pop up in your default browser).
#!/bin/bash
if [ $# -lt 1 ] ; then
echo "gman takes a man page, if found and formats it into html."
echo "Usage: gman [manfile]"
exit 2
fi
a=`man -aw $* |head -1`
if test x$a = x ; then
echo "Can't find $1"
exit 1
fi
# Figures out if it is a normal man page or something else (gz).
b=`man -aw $* |head -1 |grep "gz"`
echo $b
if test x$b = x ; then
groff -man $a -Thtml >|/tmp/tmp.html
else
gzcat $b |groff -man -Thtml >|/tmp/tmp.html
fi
qlmanage -p /tmp/tmp.html >/dev/null 2&>1Check out this resource!
Most of my vim tips are on my .vimrc (my dotfiles here https://github.com/carlesfe/dotfiles/blob/master/.vimrc) and on the links on my homepage: http://mmb.pcb.ub.es/~carlesfe/#programming_h3. The .txt that op linked feels a bit out of context :)
^x ^e
It opens up the exported EDITOR with a tmp file containing whatever is on the command line.Using SSH, especially on campus/in a train/other places where a wifi connection doesn't long, mosh is really a godsend. In places where mosh isn't practical or available, the following combos are really good to know:
<RETURN> ~ . # end ssh connection
<RETURN> ~ ? # show available commands
Paired with autossh which will reconnect by itself, it really takes the pain out of traveling while doing remote work.Oh, and when you need to know what the decimal value of 0x65433 is, it's good to know that bash can do stuff like that:
$ echo $((16#65433))
414771
Reading the bash man page is not a bad idea in itself... ls *.png | parallel convert {} {.}.jpgThis one blew my mind
ssh -fN -o ServerAliveInterval="240" -R 2222:localhost:22 example.com
(And on example.com ssh -p 2222 localhost)This lets you easily keep the tunnel open long-term. Why?
-f Background the ssh process (don't need nohup)
-N Don't run any command
-o... Make ssh do the work of keeping the session alive forever'sshfs_mount' is not really stable, any network failure will be troublesome'
To avoid trouble with remote backups and other long running processes, I always add the following to the end of ~/.ssh/config or /etc/ssh_config:
Host *
ServerAliveInterval 300 while [ true ]; do sleep 1000; done
Just using: sleep 1000; exit
means you can't make new connections after 17 minutes.I enjoyed your list.
Bash and zsh support a surprising amount of emacs editing functionality. Cursor navigation (M-b, M-f, C-a, C-e), text selection (C-space), copy/paste (C-w, M-w, C-y, M-y), and undo (C-_).
** glob function pushcd {
if [ $# -eq 0 ]; then
pushd ~ > /dev/null
else
pushd "$@" > /dev/null
fi
}
alias cd='pushcd'
alias b='popd > /dev/null'
Then cd saves the history of visited directories and b navigates backwards, e.g.: ~$ cd /tmp
/tmp$ cd /usr
/usr$ b
/tmp$ b
~$All extremely useful, my favourite being the .inputrc rebindings of up and down to search history. Takes a little getting used to but is great once you are (good luck to anyone else trying to use your terminal though ;))
In .inputrc
"\C-p": history-search-backward
"\C-n": history-search-forward
Also I found the following settings to be very useful: # List the possible completions when Tab is pressed
set show-all-if-ambiguous on
#tab complete without needing to get the case right
set completion-ignore-case onThen use fc to get that command back in a vi editing context, change what I want and :wq
The resulting command is immediately executed. This process can be really fast compared to manually constructing long piped commands.
* Read on 'ssh-keygen' to avoid typing passwords every time you ssh
He meant ssh-agent?I understand layers (probably moreso than most), but this is something that always bothers me a lot from a practicality perspective. My passwords are encrypted at rest via encrypted filesystems. If you are running things on my personal machine as my user account, I'm already being keylogged and/or am executing arbitrary code for you. If I'm logged into somewhere via ssh (hint: I am whenever I have a network connection), you can just scan my ssh config and use my ssh key anyway. From there, you can probably do a lot of other nasty stuff. ssh-agent won't really prevent this. It will prevent the malware from working again when I reboot until I log into another remote host (which I've established I do a lot) where the keylogger now gets me.
It's possible, but extremely unlikely that I have might have completely read-only media. I could be using my TPM device to protect from from booting and executing modified system states. Some of this might prevent you from easily persisting the keylogger threat across reboots. I might also have a module or something that calculate checksums on startup of critical things, have ridiculous anti-exfil outgoing connection policies, etc that prevent all but the most targeted attacks.
I don't have all of that in place. (In particular, to anyone generating a profile for me, I don't build detailed outgoing packet filter rules (you are welcome).) But what I do have in place will probably prevent me from getting my initial passphase keylogged if I used ssh-agent since it's likely (although this isn't strictly necessary) that I'm going to get attacked again after I start logging into remote hosts. So they can't steal my password, but they do have unrestricted access to my user account and the remote users I can log into. That complicates things, but is still a major security failure, to the point where them having the passphrase to my key isn't super important. I mean, in this scenario, they already have the absolute best input vector (a history of me logging in so they can execute attacks at the times I'm supposed to be logging in, as well as direct access to the systems from my ip addresses) to the point where using my ssh key from elsewhere is probably a worse a idea.
/this/is/some/very/nested/directory/
and you need to move to almost the same structure /this/be/some/very/nested/directory/
then you might benefit from function bcd {
cd ${PWD/$1/$2}
}find . -name somefile.txt -print
Then copy and paste the results manually into a cd command for example. I feel like there's a much better way somewhere.
Here is an example from the man page: >For example, the following command will copy the list of >files and directories which start with > an uppercase letter in the current directory >to destdir:
/bin/ls -1d [A-Z]* | xargs -J % cp -rp % destdir
You can use this with find really nicely.find . -name somefile.txt -print0 | xargs -0 -J % cp -rp % destdir
Note the -print0 and -0 flags (zero). This will use a null byte as a separator instead of spaces to avoid failing on files with spaces in their names.
autocmd FileType gitcommit setlocal spellUmmm, "apt-" isn't a "Unix trick..." It's specific to linux distros which use the "Aptitude" package manager.
Linux != Unix
To pipe all the contents of your current directory (including dotfiles) to the destination machine.
Greetings from LSI-UPC!
PS: hey, we're neighbors! :)
tar czf - . | ssh destination "cd /remote/dir; tar xz"
tar czf - | ssh destination 'cd /remote/dir && tar xzf -'
Test that `cd` or one day you'll end up extracting in the wrong place.Then I learned to love rsync -av. The benefits are many-fold.
Perform the previous command as root. Great if you continually forget which of your scripts need to be run as root and which don't.
and since one month i have my first own macbook. totally helpful to get in touch with some magic in the console.
thank to everybody, who makes my working life easier =)
is something I use a lot - plus xargs sometimes
On Ubuntu/Debian systems, it is packaged as `ack-grep`.
Searches all the files in current directory and all subdirectories for files that contain "hello". Add -l option to grep to only display the filenames instead of filename and match.
mv p1080<100-300>.jpg folderx/
to move p1080100.jpg through p1080300.jpg to a new folder.
Still not available on bash or more common shells?
mv p1080{100..300}.jpg folderx/A sequence expression takes the form {x..y[..incr]}, where x and y are either integers or single characters, and incr, an optional increment, is an integer. When integers are supplied, the expression expands to each number between x and y, inclusive. Supplied integers may be pre‐fixed with 0 to force each term to have the same width. When either x or y begins with a zero, the shell attempts to force all generated terms to contain the same number of digits, zero-padding where necessary. When characters are supplied, the expression expands to each character lexicographically between x and y, inclusive. Note that both x and y must be of the same type. When the increment is supplied, it is used as the difference between each term. The default increment is 1 or -1 as appropriate.
https://github.com/ggreer/the_silver_searcher
I think you might like it.