Machine-readable LVM report
Nov. 8, 2019, 10:51 p.m.lvm fullreport --reportformat json
lvm fullreport --reportformat json
This morning after waking my ThinkPad P52s (Windows 10 x64) from sleep the following happened:
Thunderbolt controller is enabled in BIOS. "Thunderbolt in BIOS Assist Mode" is disabled.
It looks like Power Delivery is not being negotiated between the power adapter and the laptop due to (malfunctioning?) Thunderbolt controller.
What I've tried so far:
echo 1 >/sys/bus/wmi/devices/86CCFD48-205E-4A77-9C48-2021CBEDE341/force_power
, but the controller does not show up under /sys/bus/thunderbolt
. lspci
just hangs for an unknown reason.Unfortunately I do not have any true Thunderbolt peripherals (only USB 1.0/2.0 with USB-C adapter cables) to plug in an see if that will wake the Thunderbolt controller up.
It is unclear whether it is a hardware issue or some catch 22 with controller not waking up because it wants the firmware update and firmware update not being applied because the controller is not waking up.
UPD: Had the motherboard replaced few days ago which fixed the issue for myself. But it looks like Lenovo has acknowledged the issue and the fix for P52s is pending: https://pcsupport.lenovo.com/gb/en/solutions/ht508988
There are numerous reports (first, second, third results on Google) on the Internet about an issue with Internet Connection Sharing in Windows 10. Since the 1607 release (or 1703 for some people) ICS stops working after a reboot. The only way to get it working again for me was to disable and then re-enable the sharing. Resetting Windows Firewall settings, suggested by some people, didn't work.
You can automate the disable/enable steps with a simple Powershell script run as a scheduled task on system startup, like this one:
$m = New-Object -ComObject HNetCfg.HNetShare
$private = $m.EnumEveryConnection |? { $m.NetConnectionProps.Invoke($_).Name -eq "Loopback0" }
$private_config = $m.INetSharingConfigurationForINetConnection.Invoke($private)
$public = $m.EnumEveryConnection |? { $m.NetConnectionProps.Invoke($_).Name -eq "Wi-Fi" }
$public_config = $m.INetSharingConfigurationForINetConnection.Invoke($public)
$private_config.DisableSharing()
$public_config.DisableSharing()
Start-Sleep 1
$public_config.EnableSharing(0)
$private_config.EnableSharing(1)
if you're after a quick and easy fix. Some users reported Windows Firewall filling up with duplicate rules created on every enable/disable of the ICS though.
There is a better fix, however.
Dissatisfied with all proposed workarounds I've tried searching for the reports on this issue on Microsoft TechNet directly. The issue has been there for years, so there are plenty.
One thread mentioned creating the DWORD HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\SharedAccess\EnableRebootPersistConnection
registry key, setting it to 1
and setting the Internet Connection Sharing service startup type to "Automatic". This fixed the problem!
The mentioned registry key was introduced with the 1709 release in KB4054517. See KB4055559 for more information.
Let's suppose you want to diff outputs of two scripts which operate on the same resource (file). Compare contents of the file before and after a transformation in a single pass, for example.
With process substitution, like diff <(cat myfile) <(reformat myfile; cat myfile)
both substitutions are started in separate subshells at the same time, so you would need a semaphore, to ensure the second process substitution is started after after the first one - otherwise you might hit a race condition.
One option is to use a named pipe for that, but it involves the creation (and cleanup) of the pipe device file.
Another option is to use a co-process (Bash 4+) for that. cat
command running as the co-process would basically act as an anonymous pipe!
echo BEFORE >data.txt
(
coproc cat
diff -du \
<(sleep 5; cat data.txt; echo >&"${COPROC[1]}") \
<(read <&"${COPROC[0]}"; echo AFTER >data.txt; cat data.txt)
)
(sleep
is for demonstration purposes only)
will output
--- /dev/fd/62 2018-11-15 21:41:17.771271807 +0000
+++ /dev/fd/61 2018-11-15 21:41:17.771271807 +0000
@@ -1 +1 @@
-BEFORE
+AFTER
Sometimes you may need to capture an exit code of a command while keeping the errexit
option enabled during execution of that command.
|| rc=$?
or wrapping the command in an if
statement, does not work correctly for compound commands and functions as ||
, if
, while
, etc. will completely disable the errexit
option for that command, therefore failures in the middle of a function will not cause that function to fail.
Example:
set -euo pipefail
failing_fn () {
return 5
}
complex_fn () {
true
failing_fn
echo 'Should not see me'
}
rc=UNCHANGED
complex_fn || rc=$?
echo "$rc"
outputs
Should not see me
UNCHANGED
One could use the PIPESTATUS
trick, like complex_fn | cat; rc=${PIPESTATUS[0]}
but it does not work with -o pipefail
Here's one of the ways to handle this:
set +e
(set -e; complex_fn)
rc=$?
set -e
echo "$rc"
outputs 5
This method also works with pipes and -o pipefail
:
set +e
(set -e; true | complex_fn | true)
rc=$?
set -e
echo "$rc"
also outputs 5
There is a way to declare (-n
) a variable in Bash as a reference to another variable (kind of pointer). This allows us to pass multiple arrays to functions or create utility functions like:
# Check if variable is set. Will return true even when the value is an empty string.
# Usage: is_set VAR_NAME
is_set () {
declare -n __var="$1"
[[ "${__var+set}" = 'set' ]]
}
or
# Translate characters in a string
# Usage: translate STR FROM_CHARS TO_CHARS
translate () {
declare str="$1"
declare -n __from="$2"
declare -n __to="$3"
declare i
[[ "${#__from[@]}" = "${#__to[@]}" ]] || return 1
for i in "${!__from[@]}"; do
str="${str//"${__from[$i]}"/"${__to[$i]}"}"
done
printf '%s\n' "$str"
}
$ declare -a from=(a b)
$ declare -a to=(c d)
$ translate "abc" from to
cdc
or
pushopts () {
declare -n __opts="$1"
readarray -t __opts < <(shopt -po)
}
popopts () {
declare -n __opts="$1"
declare cmd
for cmd in "${__opts[@]}"; do
eval "$cmd"
done
}
$ set -e
$ pushopts BACKUP
$ set +e
$ popopts BACKUP
$ shopt -po errexit
set -o errexit
errexit
is not propagated into command substitutions, so you cannot do this:
set -e
OPTS=$(shopt -po)
set +e
eval "$OPTS"
but it is propagated into process substitutions.
set -e
# Backup restore commands into an array
declare -a OPTS
readarray -t OPTS < <(shopt -po)
set +e
# Restore options
declare cmd
for cmd in "${OPTS[@]}"; do
eval "$cmd"
done
Check:
$ shopt -po errexit
set -o errexit
In Bash, time
is a built-in reserved word you can prepend to a pipeline to measure the duration of executed commands. It implements a subset of features of the original time
binary, but does not involve shelling-out.
time
built-in will output the measurements to STDERR. Under some circumstances (time
is used to measure a failing function executed in a subshell with errexit enabled), the STDERR of time
will leak into the executed command.
Example:
Let's define a couple of functions first
$ failing_fn () { false; }
$ successful_fn () { true; }
The following will result in measurements written into testfile
(while it shouldn't, redirect happens in the subshell)
$ time (set -e; failing_fn 2>./testfile)
$ cat testfile
real 0m0.000s
user 0m0.000s
sys 0m0.000s
This does not happen if the subshell command is not a function
$ time (set -e; false 2>./testfile)
real 0m0.000s
user 0m0.000s
sys 0m0.000s
$ cat testfile
it also doesn't happen when the failing function does not fail the pipeline (errexit is not enabled)
$ time (set +e; failing_fn 2>./testfile)
real 0m0.000s
user 0m0.000s
sys 0m0.000s
$ cat testfile
or if the function is successful
$ time (set -e; successful_fn 2>./testfile)
real 0m0.000s
user 0m0.000s
sys 0m0.000s
$ cat testfile
or when we do not use time with the subshell syntax directly
$ time eval '(set -e; failing_fn 2>./testfile)'
real 0m0.001s
user 0m0.001s
sys 0m0.000s
$ cat testfile
Oddly enough, simply adding | cat
to the pipeline inside the subshell will result in measurements output being duplicated into both STDERR of the current shell and STDERR of the subshell function
$ time (set -e; failing_fn 2>./testfile | cat)
real 0m0.001s
user 0m0.001s
sys 0m0.001s
$ cat testfile
real 0m0.001s
user 0m0.000s
sys 0m0.000s
and it works properly in case | cat
and eval
are present in the subshell (found this one by trial-and-error)
$ time (set -e; eval failing_fn 2>./testfile | cat)
real 0m0.001s
user 0m0.001s
sys 0m0.001s
$ cat testfile
Since Bash version 4.1 it is possible to dynamically allocate file descriptors greater than 10. Useful for redirections
Example:
$ testfn () {
echo "This is STDOUT"
echo "This is STDERR" 1>&2
}
$ (
# Annotate output of the current subshell so it is visible
# which file descriptor it comes from
exec 2> >(sed -e "s/^/STDERR:/") > >(sed -e "s/^/STDOUT:/")
# Unmodified output
testfn
# The folowing command will swap STDOUT and STDERR from testfn()
{ testfn 2>&${stderrfd} >&${stdoutfd}; } {stderrfd}>&1 {stdoutfd}>&2
# Need to manually close the created descriptors after use
exec {stderrfd}>&- {stdoutfd}>&-
)
STDERR:This is STDERR
STDERR:This is STDOUT
STDOUT:This is STDOUT
STDOUT:This is STDERR
Output is out of order because annotating processes run in async subshells
A while ago my daughter asked me to show her how beat-matching is done. Unfortunately we had no DJing equipment and even the entry-level MIDI controllers on Amazon are quite expensive. After some googling we've discovered projects like Fliper DJ and Traktorino, but the former wasn't quite what I've wanted and the later wasn't available at the time, so we've decided to build one ourselves.
Few knobs, buttons, wires, Arduino Uno (+ CD74HC4067 multiplexer) and here we go:
Project repository on GitHub contains the code and Traktor 2 mappings.
Put .git
in it.
More Best Practices When It Comes to Writing Docker Related Files
Scaleway has introduced the NextGen Start NVMe Cloud Servers (yes, NVME SSD) starting at €1.99/month!
puppet resource augeas setnoop \
"context=/files/etc/puppetlabs/puppet/puppet.conf/agent" \
"changes=set noop true" \
&& { systemctl try-restart puppet || service puppet condrestart; }
Lazy set combined with $(error)
will fail a recipe nicely if the user hasn't provided the value for the var
REQUIRED_VAR = $(error Please supply a value for REQUIRED_VAR)
envsubst
Kickstart default
template tries to install puppet-agent
package in the %packages
section, but the http://yum.puppetlabs.com/fedora/f27/PC1/x86_64/
repo which is set up in the kickstart file only contains puppetlabs-release-pc1
.
It looks like only Puppet 5 is supported on FC27. Puppet 5 repo package is available via different URL: http://yum.puppetlabs.com/puppet5/fedora/27/x86_64/
and name: puppet-release
There is no right or wrong, just preferences
Well designed CLI interface: ./concourse web --help
Do not use bond-slave
, team-slave
or bridge-slave
as values for the connection.type
property. These always default to to 802-3-ethernet
connection types. Set specific type (802-3-ethernet
or wifi
, etc) and the connection.master
and connection.slave-type
properties instead.
Let's say you want to redirect the STDOUT of some command to a file (a config file for example) using the (bash) shell. In ideal case destination file should not be touched if it already has exactly the same content you are going to write into it. How to do that in a single pipe?
Here's how:
echo "New contents" | diff -duaN "$target_path" - | patch --binary -s -p0 "$target_path"
#!/usr/bin/env bash
set -eu -o pipefail
to_stderr () {
>&2 cat
}
printable_only () {
tr -cd '\11\12\15\40-\176'
}
pipe_debug () {
tee >(printable_only | to_stderr)
}
to_file () {
local target_path="$1"
local restore_pipefail
# diff will return non-zero exit code if file differs, therefore
# pipefail shell attribute should be disabled for this
# special case
restore_pipefail=$(shopt -p -o pipefail)
set +o pipefail
diff -duaN "$target_path" - | pipe_debug | patch --binary -s -p0 "$target_path"
eval "$restore_pipefail"
}
md5 () {
md5sum -b | cut -f 1 -d ' '
}
sample_binary_data () {
local i
for (( i=0; i<=255; i++ )); do
printf "\x$(printf %x "$i")"
done
}
sample_text_data () {
cat <<EOF
Here be dragons
EOF
}
testfile='./testfile'
echo "Binary data MD5 $(sample_binary_data | md5)"
echo "Text data MD5: $(sample_text_data | md5)"
sample_text_data >"$testfile"
echo "$testfile is going to be modified"
sample_binary_data | to_file "$testfile"
echo "$testfile is NOT going to be modified"
sample_binary_data | to_file "$testfile"
echo "$testfile MD5: $(md5 <"$testfile")"
echo "$testfile is going to be modified"
sample_text_data | to_file "$testfile"
echo "$testfile is NOT going to be modified"
sample_text_data | to_file "$testfile"
echo "$testfile MD5: $(md5 <"$testfile")"
Sample output
Binary data MD5 e2c865db4162bed963bfaa9ef6ac18f0
Text data MD5: 890923a3ff411987e645531cc33548f6
./testfile is going to be modified
--- ./testfile 2017-07-07 07:21:39.853604436 +0100
+++ - 2017-07-07 07:21:39.856596473 +0100
@@ -1 +1,2 @@
-Here be dragons
+
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
\ No newline at end of file
./testfile is NOT going to be modified
./testfile MD5: e2c865db4162bed963bfaa9ef6ac18f0
./testfile is going to be modified
--- ./testfile 2017-07-07 07:21:39.994605593 +0100
+++ - 2017-07-07 07:21:40.146792083 +0100
@@ -1,2 +1 @@
-
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
\ No newline at end of file
+Here be dragons
./testfile is NOT going to be modified
./testfile MD5: 890923a3ff411987e645531cc33548f6
I'm an oldfag. I love playing old games "Baldur's Gate" series or "Heroes of Might & Magic II". I happen to own the original Gold Edition CD of the latter one which I enjoy playing with my daughters occasionally. The CD contains the state of the art soundtrack which is an essential part of the game.
Unfortunately, this version of the game doesn't run well on the latest build of the Windows 10. Even with some workarounds applied game tends to crash now and then.
The version distributed by GOG (which is basically a repackaged DOS version of it) works, but it lacks network play and has some audio tracks replaced with the different ones for some reason.
My primary operating system, for the time being, is Windows 10 and I do not have plans to change this in the near future, therefore the obvious choice is to run the game in a VM. Windows XP/7 require an additional license, so I've decided to give Linux/Wine a shot. VirtualBox was used for the hypervisor as I use it for the other things anyway.
The tricky part was to get the CD audio working. By passing the host CD drive to the VM I was able to access the data track, but not the audio tracks. Passing the CD as ISO image wouldn't work either, as the ISO format does not support the audio tracks. The solution was to create BIN/CUE/CCD image and load it into the emulated CD drive inside of the VM.
The result? Well, see for yourself :)
Libvirt allows you to create a network definition with all the virtual functions (VF) from the specified SR-IOV physical function (PF). It will assign one of the available VFs to the guest VM connected to such network automatically when it's powered on. This allows you to avoid hardcoding of the VF PCI addresses into the configuration of the guest.
To enable SR-IOV for the static vNIC on the Cisco UCS You need to create a Dynamic vNIC Connection Policy with the desired number of the dynamic vNICs and assign it to the static vNIC.
You will also need to enable VT-d in the BIOS policy of the service profile (by selecting the predefined SRIOV BIOS policy for example) and enable the IOMMU support for your Linux kernel (see the "17.1.6.2. Using SR-IOV" section of the "Guest virtual machine device configuration" chapter from the RH Virtualization Deployment and Administration Guide)
Typical example, like the one from the section "17.1.6.4. Setting PCI device assignment from a pool of SR-IOV virtual functions" of the mentioned chapter might not work on the UCS:
<network>
<name>passthrough</name> <!-- This is the name of the file you created -->
<forward mode='hostdev' managed='yes'>
<pf dev='enpXs0f0'/> <!-- Use the netdev name of your SR-IOV devices PF here -->
</forward>
</network>
In my case I was getting the internal error: missing IFLA_VF_INFO in netlink response
error after trying to power on the VM connected to the "passthrough" network.
In order to work properly, the SR-IOV VF needs the Port Profile and the Port Profile Client created on the UCS (VM tab in the GUI, see the Cisco UCS Manager VM-FEX for KVM GUI Configuration Guide for more details on configuring port profiles on the UCS) and specified in the Libvirt network or interface definition. This allows you to specify the allowed VLANs for the VM configured to use that port profile.
Working Libvirt network definition looks like this (notice the <driver name='vfio'/>
I've had to add as well):
<network>
<name>passthrough</name>
<forward mode='hostdev' managed='yes'>
<pf dev='enpXs0f0'/>
<driver name='vfio'/>
</forward>
<portgroup name='libvirt_port_group1' default='yes'>
<virtualport type='802.1Qbh'>
<parameters profileid='UCS_Port_Profile'/>
</virtualport>
</portgroup>
</network>
And the network interface for the VM can be defined like:
<interface type='network'>
<mac address='52:54:00:ec:24:f1'/>
<source network='passthrough' portgroup='libvirt_port_group1'/>
</interface>
One of the enpXs0f0 virtual functions (total number depends on the Dynamic vNIC Connection Policy assigned to the static vNIC) will be consumed by that VM as soon as you power it on.
Combine water and carbon dioxide. If you use some energy take a part of oxygen out - you will be left with the glucose - a simple sugar. Plants use the energy of the sun to run this process all over the planet every day.
Our bodies revert that reaction by adding oxygen back to the glucose (that's the reason you have to breathe :) ) to release the stored energy (water and exhaled carbon dioxide are the waste products). The actual process of converting that energy into muscular(mechanical) one is a bit more complicated, involving the conversion of glucose into the more suitable fuel by the mitochondria.
1 gram of glucose contains 4 calories of energy. You burn that much energy by running for the 40 meters.
Fat is the conserved fuel our body is able to store in a practically infinite amount.
Why and how do we accumulate the fat? Our bodies burn energy at some rate. This rate is higher during the exercise and lowers during the rest. Consumed carbohydrates are broken down into the glucose and used as the primary energy source by the organs (except for the heart, which mainly uses fatty acids for fuel). An insignificant amount of sugar is stored in the muscles in the form of glycogen for quick access, Some glycogen is stored in the liver and released on demand, but not much (enough to sustain a few hour exercise).
If the glycogen stores in your body are already full, and the sugar enters your bloodstream at a higher rate than your body is able to burn it - any excess will be stored as fat for the later consumption.
Some sugars you eat are simple (like glucose, fructose) and easy to digest. Simple sugars combined into complex chains (starches for example) are harder to digest, as they need to be broken down first. Some sugar chains, cellulose, for example, cannot be broken down by the human body at all, therefore pass through it and do not contribute to the overall calory intake.
The simpler sugar is - the quicker it will reach your bloodstream - the greater chance it will be converted into fat.
On the other hand - a can of Coke (33 grams of table sugar) consumed after a 10km run would be used to replenish the glycogen stores and won't end up as a fat.
For both simple and complex carbohydrates 1 gram contains 4 calories of energy, Dietary fiber (cellulose for example) is a carbohydrate as well, but, as mentioned before, it is not absorbed by the humans, as our bodies lack the enzymes which are needed to break it down.
While protein also provides 4 calories per 1 gram - it's primary function is to provide building blocks for the body. Protein will be converted into glucose when glycogen stores in the muscles and the liver are exhausted. While there is a pathway for the excess protein to turn into fat - it is very unlikely to happen. This doesn't mean one can safely replace carbohydrates with protein in the diet - consuming too much of it may overload liver and kidneys,
Another source of energy is the fat we eat. It contains approximately 9 calories per 1 gram. Consumed fat is broken into fatty acids first. Some of the consumed fat is used as the fuel, the rest is used for the different purposes (like an insulator for the nerves and organs or hormone production for example). Fat will slow down the digestion of the carbohydrates and/or proteins when consumed together.
Body Mass Index is simple but useless. It doesn't differentiate between muscle mass and fat mass.
The person above is the Arnold Schwarzenegger. According to the BMI (height 188cm, weight 106kg) he was obese in 1974, the year this photo was taken :)
There are few variables we can change to affect body mass - muscle mass, fat tissue, and water. Changing the amount of water in your body is neither effective nor healthy way to affect the body weight, therefore we are left with only two variables.
Fitness is rarely about losing weight. Usually, it's about changing the body composition. Being big boned doesn't make you look fat. Being muscular doesn't make you look fat. Fat makes you look fat.
Basal Metabolic Rate tells us the amount of energy we burn during the rest per day. Your liver, brain, muscle, kidneys, heart and other organs constantly require energy supply just to keep you alive. Even if you stay completely idle throughout the day - you will still burn 1000-2500 calories (actual amount depends on the lean body mass of the individual). BMR is the bulk of the daily energy expenditure even for many athletes.
Your approximate BMR is calories per day.
You can reduce your body fat percentage in a number of ways. The most obvious one - simply reduce your daily calory intake to the amount which is less than your BMR combined with any additional calories spent (like during exercise). In other words - eat less - weigh less.
While the diet is the primary way of changing the body composition - it can lead to the undesired result when used as the only way.
Reducing the calory intake below the amount spent will eventually switch the body into the starvation mode. This will trigger the release and use of the stored fat for fuel. It will also trigger the gluconeogenesis - the process of converting proteins and fats into glucose. Not all organs can use fats as the fuel - our brain requires at least 10g of glucose per day, the remaining energy requirements of the brain are satisfied by the alternative fuel produced by the liver from the fat. The body may break down the muscle tissues, which are made of protein in case there is not enough of it in the bloodstream to convert into glucose. In other words - you may end up losing both fat and a significant amount of the muscle mass as a result - depends on how extreme the diet is.
Increased protein intake can mitigate the muscle mass loss problem to some extent, but it's not a silver bullet and you can't consume a lot of it due to the reasons explained earlier.
It's hard to spot muscle mass loss if you are overweight - a layer of fat may mask it.
The consequence of losing the muscle mass is the daily energy expenditure (BMR) decrease (as it directly depends on the lean body mass). Lower BMR means the energy demand is now lower than it was before, therefore calory intake should be reduced or the amount of exercise has to be increased. Ever heard of the yo-yo weight cycling effect? Decreased BMR is one of the reasons people start gaining, even more, weight when they complete the diet and return to their usual eating habits.
When diet is combined with an aerobic exercise like running, cycling, swimming - energy consumption is accelerated. A lot of calories are burned during the aerobic exercise - approximately 100 calories per 1km of running or 5km of cycling for example (it depends on your weight and age and exercise conditions).
Human body prefers fat as the fuel source during the low-intensity exercise, such as aerobic one, therefore it's a good choice to lose fat. The duration is important - 40 minutes or more is the way to go.
Fat is very energy dense - with 9 calories per 1 gram, it's 9000 calories per 1 kilogram of fat. That's 90 kilometers of running alone! Think of it this next time you eat your 200 calory snack :)
The best way to affect your body composition is to grow muscle mass while keeping slight calory deficit and doing occasional aerobic exercise. Increased muscle mass will result in higher BMR. As the baseline energy demand will grow - you'll have to eat more, simply to keep slight calory deficit constant. That's where the "to lose weight you have to eat more, not less" expression stems from. It takes a longer time to achieve the goal, but the result is much more sustainable.
So, how do you become more muscular? The answer is simple - you lift. You lift heavy weights. How heavy? Think weight, which you can lift 8-12 times max. The weight will be different for different types of exercise. Lifting heavy weights will:
Lifting light weights will not result in testosterone production increase. Muscle will not grow if testosterone level does not increase. No pain - no gain. You have to overload the body to trigger the response.
Testosterone is only produced when you rest(sleep), therefore you will experience the boost on the day following the strength exercise. The heavier the weight you lift and the more joints are involved in the exercise - the stronger effect it will have on the testosterone production.
If you are a beginner - don't waste your time on weight machines. Most of those are isolation (single-joint) oriented and won't affect hormone production much. Dedicate first years of your training to the compound (multi-joint) exercises. The following are the classics:
Each of the mentioned above will result in a huge boost in testosterone production, but beware all three are the high-risk exercises and will result in injury if performed improperly. A proper warm-up before lifting heavy weights is essential. Please learn about proper form and common mistakes (see deadlift, squat and bench press mistakes for example) before starting. Start with lighter weights, only go heavier if you are completely confident and comfortable with the exercise.
Proper rest is required to allow full muscle recovery between workouts. Too frequent exercise may lead to overtraining.
Due to the physiological differences, it's easier for the males to gain muscle mass compared to the females. It's nearly impossible for the most females to become as muscular as the Arnie on the photo above, simply because testosterone production volume is lower in females than males.
The human body needs amino acids to repair and grow the muscle tissue. There are 20 common amino acids, nine of which are essential (our body cannot synthesize those from other common amino acids). We get amino acids from the protein we consume. Different proteins contain different sets and amounts of the mentioned common amino acids. Complete proteins contain all nine essential amino acids. Meat, dairy, eggs, soy, and fish are sources of the complete protein.
You'll have to adjust your protein intake after starting the weight training, but don't go crazy about it. 1.5 grams of protein per one kilogram of the desired body mass is enough in most cases (for an 80kg person - that's 120 grams of protein per day). For the reference - 100 grams of chicken breast contain 31 gram of complete protein, one egg (one of the best protein sources) has 6 grams of protein.
Eat clean. High-calory fast carbohydrates are too expensive - think in terms of kilometers of running needed to burn those.
Run a few km twice a week - that's extra several hundred of calories burned.
Do 40 minutes of weight lifting two-three times a week. Spend those 40 minutes working out, not looking at your phone.
Walk.
And sleep well.
Finally replaced old crappy git prompt with the vanilla one from the contrib and did some tuning to the Bash history
# git
if [[ -f ~/.git-completion.bash ]]; then
. ~/.git-completion.bash
fi
if [[ -f ~/git-prompt.sh ]]; then
. ~/git-prompt.sh
fi
PS1='[\u@\h \W$(__git_ps1 " (\[\033[1;34m\]%s\[\033[0m\])")]\$ '
GIT_PS1_SHOWDIRTYSTATE=1
GIT_PS1_SHOWUNTRACKEDFILES=1
GIT_PS1_SHOWUPSTREAM="auto"
# History (see https://sanctum.geek.nz/arabesque/better-bash-history/)
HISTFILE="${HOME}/.bash_history.$(hostnamectl --static)"
shopt -s histappend
HISTFILESIZE=1000000
HISTSIZE=1000000
HISTCONTROL=ignoreboth
HISTIGNORE='ls:bg:fg:history'
HISTTIMEFORMAT='%F %T '
shopt -s cmdhist
PROMPT_COMMAND='history -a'
Yet another hello world
Websocket Shootout: Clojure, C++, Elixir, Go, NodeJS, and Ruby
Emacs IbufferMode