neulab/tldr huggingface dataset:
SUPER BLOCK As said above, super block is handled in a special way. In order to be crash safe, at least one zone in a known location must contain a valid superblock. This is implemented as a ring buffer in two consecutive zones, starting from known offsets 0, 512G and 4TiB. The values are different than on non-zoned devices. Each new super block is appended to the end of the zone, once it’s filled, the zone is reset and writes continue to the next one. Looking up the latest super block needs to read offsets of both zones and determine the last written version.
The amount of space reserved for super block depends on the zone size. The secondary and tertiary copies are at distant offsets as the capacity of the devices is expected to be large, tens of terabytes. Maximum zone size supported is 8GiB, which would mean that eg. offset 0-16GiB would be reserved just for the super block on a hypothetical device of that zone size. This is wasteful but required to guarantee crash safety.
There’s a character special device /dev/btrfs-control with major and minor numbers 10 and 234 (the device can be found under the misc category).
$ ls -l /dev/btrfs-control crw------- 1 root root 10, 234 Jan  1 12:00 /dev/btrfs-control
The device accepts some ioctl calls that can perform following actions on the filesystem module:
•   scan devices for btrfs filesystem (ie. to let multi-device filesystems mount automatically) and register them with the kernel module
•   similar to scan, but also wait until the device scanning process is finished for a given filesystem
•   get the supported features (can be also found under /sys/fs/btrfs/features)
The device is created when btrfs is initialized, either as a module or a built-in functionality and makes sense only in connection with that. Running eg. mkfs without the module loaded will not register the device and will probably warn about that.
In rare cases when the module is loaded but the device is not present (most likely accidentally deleted), it’s possible to recreate it by
# mknod --mode=600 /dev/btrfs-control c 10 234
or (since 5.11) by a convenience command
# btrfs rescue create-control-device
The control device is not strictly required but the device scanning will not work and a workaround would need to be used to mount a multi-device filesystem. The mount option device can trigger the device scanning during mount, see also btrfs device scan.
It is possible that a btrfs filesystem contains multiple block group profiles of the same type. This could happen when a profile conversion using balance filters is interrupted (see btrfs-balance(8)). Some btrfs commands perform a test to detect this kind of condition and print a warning like this:
WARNING: Multiple block group profiles detected, see 'man btrfs(5)'. WARNING:   Data: single, raid1 WARNING:   Metadata: single, raid1
The corresponding output of btrfs filesystem df might look like:
WARNING: Multiple block group profiles detected, see 'man btrfs(5)'. WARNING:   Data: single, raid1 WARNING:   Metadata: single, raid1 Data, RAID1: total=832.00MiB, used=0.00B Data, single: total=1.63GiB, used=0.00B System, single: total=4.00MiB, used=16.00KiB Metadata, single: total=8.00MiB, used=112.00KiB Metadata, RAID1: total=64.00MiB, used=32.00KiB GlobalReserve, single: total=16.25MiB, used=0.00B
There’s more than one line for type Data and Metadata, while the profiles are single and RAID1.
This state of the filesystem OK but most likely needs the user/administrator to take an action and finish the interrupted tasks. This cannot be easily done automatically, also the user knows the expected final profiles.
In the example above, the filesystem started as a single device and single block group profile. Then another device was added, followed by balance with convert=raid1 but for some reason hasn’t finished. Restarting the balance with convert=raid1 will continue and end up with filesystem with all block group profiles RAID1.
Note If you’re familiar with balance filters, you can use convert=raid1,profiles=single,soft, which will take only the unconverted single profiles and convert them to raid1. This may speed up the conversion as it would not try to rewrite the already convert raid1 profiles.
Having just one profile is desired as this also clearly defines the profile of newly allocated block groups, otherwise this depends on internal allocation policy. When there are multiple profiles present, the order of selection is RAID6, RAID5, RAID10, RAID1, RAID0 as long as the device number constraints are satisfied.
Commands that print the warning were chosen so they’re brought to user attention when the filesystem state is being changed in that regard. This is: device add, device delete, balance cancel, balance pause. Commands that report space usage: filesystem df, device usage. The command filesystem usage provides a line in the overall summary:
Multiple profiles:                 yes (data, metadata)
The COW mechanism and multiple devices under one hood enable an interesting concept, called a seeding device: extending a read-only filesystem on a single device filesystem with another device that captures all writes. For example imagine an immutable golden image of an operating system enhanced with another device that allows to use the data from the golden image and normal operation. This idea originated on CD-ROMs with base OS and allowing to use them for live systems, but this became obsolete. There are technologies providing similar functionality, like unionmount, overlayfs or qcow2 image snapshot.
The seeding device starts as a normal filesystem, once the contents is ready, btrfstune -S 1 is used to flag it as a seeding device. Mounting such device will not allow any writes, except adding a new device by btrfs device add. Then the filesystem can be remounted as read-write.
Given that the filesystem on the seeding device is always recognized as read-only, it can be used to seed multiple filesystems, at the same time. The UUID that is normally attached to a device is automatically changed to a random UUID on each mount.
Once the seeding device is mounted, it needs the writable device. After adding it, something like remount -o remount,rw /path makes the filesystem at /path ready for use. The simplest usecase is to throw away all changes by unmounting the filesystem when convenient.
Alternatively, deleting the seeding device from the filesystem can turn it into a normal filesystem, provided that the writable device can also contain all the data from the seeding device.
The seeding device flag can be cleared again by btrfstune -f -s 0, eg. allowing to update with newer data but please note that this will invalidate all existing filesystems that use this particular seeding device. This works for some usecases, not for others, and a forcing flag to the command is mandatory to avoid accidental mistakes.
Example how to create and use one seeding device:
# mkfs.btrfs /dev/sda # mount /dev/sda /mnt/mnt1 # ... fill mnt1 with data # umount /mnt/mnt1 # btrfstune -S 1 /dev/sda # mount /dev/sda /mnt/mnt1 # btrfs device add /dev/sdb /mnt # mount -o remount,rw /mnt/mnt1 # ... /mnt/mnt1 is now writable
Now /mnt/mnt1 can be used normally. The device /dev/sda can be mounted again with a another writable device:
# mount /dev/sda /mnt/mnt2 # btrfs device add /dev/sdc /mnt/mnt2 # mount -o remount,rw /mnt/mnt2 # ... /mnt/mnt2 is now writable
The writable device (/dev/sdb) can be decoupled from the seeding device and used independently:
# btrfs device delete /dev/sda /mnt/mnt1
As the contents originated in the seeding device, it’s possible to turn /dev/sdb to a seeding device again and repeat the whole process.
A few things to note:
•   it’s recommended to use only single device for the seeding device, it works for multiple devices but the single profile must be used in order to make the seeding device deletion work
•   block group profiles single and dup support the usecases above
•   the label is copied from the seeding device and can be changed by btrfs filesystem label
•   each new mount of the seeding device gets a new random UUID
RAID56 STATUS AND RECOMMENDED PRACTICES The RAID56 feature provides striping and parity over several devices, same as the traditional RAID5/6. There are some implementation and design deficiencies that make it unreliable for some corner cases and the feature should not be used in production, only for evaluation or testing. The power failure safety for metadata with RAID56 is not 100%.
Metadata Do not use raid5 nor raid6 for metadata. Use raid1 or raid1c3 respectively.
The substitute profiles provide the same guarantees against loss of 1 or 2 devices, and in some respect can be an improvement. Recovering from one missing device will only need to access the remaining 1st or 2nd copy, that in general may be stored on some other devices due to the way RAID1 works on btrfs, unlike on a striped profile (similar to raid0) that would need all devices all the time.
The space allocation pattern and consumption is different (eg. on N devices): for raid5 as an example, a 1GiB chunk is reserved on each device, while with raid1 there’s each 1GiB chunk stored on 2 devices. The consumption of each 1GiB of used metadata is then N * 1GiB for vs 2 * 1GiB. Using raid1 is also more convenient for balancing/converting to other profile due to lower requirement on the available chunk space.
Missing/incomplete support When RAID56 is on the same filesystem with different raid profiles, the space reporting is inaccurate, eg. df, btrfs filesystem df or btrfs filesystem usge. When there’s only a one profile per block group type (eg. raid5 for data) the reporting is accurate.
When scrub is started on a RAID56 filesystem, it’s started on all devices that degrade the performance. The workaround is to start it on each device separately. Due to that the device stats may not match the actual state and some errors might get reported multiple times.
The write hole problem.
A storage model is a model that captures key physical aspects of data structure in a data store. A filesystem is the logical structure organizing data on top of the storage device.
The filesystem assumes several features or limitations of the storage device and utilizes them or applies measures to guarantee reliability. BTRFS in particular is based on a COW (copy on write) mode of writing, ie. not updating data in place but rather writing a new copy to a different location and then atomically switching the pointers.
In an ideal world, the device does what it promises. The filesystem assumes that this may not be true so additional mechanisms are applied to either detect misbehaving hardware or get valid data by other means. The devices may (and do) apply their own detection and repair mechanisms but we won’t assume any.
The following assumptions about storage devices are considered (sorted by importance, numbers are for further reference):
1. atomicity of reads and writes of blocks/sectors (the smallest unit of data the device presents to the upper layers)
2. there’s a flush command that instructs the device to forcibly order writes before and after the command; alternatively there’s a barrier command that facilitates the ordering but may not flush the data
3. data sent to write to a given device offset will be written without further changes to the data and to the offset
4. writes can be reordered by the device, unless explicitly serialized by the flush command
5. reads and writes can be freely reordered and interleaved
The consistency model of BTRFS builds on these assumptions. The logical data updates are grouped, into a generation, written on the device, serialized by the flush command and then the super block is written ending the generation. All logical links among metadata comprising a consistent view of the data may not cross the generation boundary.
WHEN THINGS GO WRONG No or partial atomicity of block reads/writes (1)
•   Problem: a partial block contents is written (torn write), eg. due to a power glitch or other electronics failure during the read/write
•   Detection: checksum mismatch on read
•   Repair: use another copy or rebuild from multiple blocks using some encoding scheme
The flush command does not flush (2)
This is perhaps the most serious problem and impossible to mitigate by filesystem without limitations and design restrictions. What could happen in the worst case is that writes from one generation bleed to another one, while still letting the filesystem consider the generations isolated. Crash at any point would leave data on the device in an inconsistent state without any hint what exactly got written, what is missing and leading to stale metadata link information.
Devices usually honor the flush command, but for performance reasons may do internal caching, where the flushed data are not yet persistently stored. A power failure could lead to a similar scenario as above, although it’s less likely that later writes would be written before the cached ones. This is beyond what a filesystem can take into account. Devices or controllers are usually equipped with batteries or capacitors to write the cache contents even after power is cut. (Battery backed write cache)
Data get silently changed on write (3)
Such thing should not happen frequently, but still can happen spuriously due the complex internal workings of devices or physical effects of the storage media itself.
•   Problem: while the data are written atomically, the contents get changed
Data get silently written to another offset (3)
This would be another serious problem as the filesystem has no information when it happens. For that reason the measures have to be done ahead of time. This problem is also commonly called ghost write.
The metadata blocks have the checksum embedded in the blocks, so a correct atomic write would not corrupt the checksum. It’s likely that after reading such block the data inside would not be consistent with the rest. To rule that out there’s embedded block number in the metadata block. It’s the logical block number because this is what the logical structure expects and verifies.
The following is based on information publicly available, user feedback, community discussions or bug report analyses. It’s not complete and further research is encouraged when in doubt.
MAIN MEMORY The data structures and raw data blocks are temporarily stored in computer memory before they get written to the device. It is critical that memory is reliable because even simple bit flips can have vast consequences and lead to damaged structures, not only in the filesystem but in the whole operating system.
Based on experience in the community, memory bit flips are more common than one would think. When it happens, it’s reported by the tree-checker or by a checksum mismatch after reading blocks. There are some very obvious instances of bit flips that happen, e.g. in an ordered sequence of keys in metadata blocks. We can easily infer from the other data what values get damaged and how. However, fixing that is not straightforward and would require cross-referencing data from the entire filesystem to see the scope.
If available, ECC memory should lower the chances of bit flips, but this type of memory is not available in all cases. A memory test should be performed in case there’s a visible bit flip pattern, though this may not detect a faulty memory module because the actual load of the system could be the factor making the problems appear. In recent years attacks on how the memory modules operate have been demonstrated (rowhammer) achieving specific bits to be flipped. While these were targeted, this shows that a series of reads or writes can affect unrelated parts of memory.
Further reading:
•   https://en.wikipedia.org/wiki/Row_hammer
What to do:
•   run memtest, note that sometimes memory errors happen only when the system is under heavy load that the default memtest cannot trigger
•   memory errors may appear as filesystem going read-only due to "pre write" check, that verify meta data before they get written but fail some basic consistency checks
DIRECT MEMORY ACCESS (DMA) Another class of errors is related to DMA (direct memory access) performed by device drivers. While this could be considered a software error, the data transfers that happen without CPU assistance may accidentally corrupt other pages. Storage devices utilize DMA for performance reasons, the filesystem structures and data pages are passed back and forth, making errors possible in case page life time is not properly tracked.
There are lots of quirks (device-specific workarounds) in Linux kernel drivers (regarding not only DMA) that are added when found. The quirks may avoid specific errors or disable some features to avoid worse problems.
•   use up-to-date kernel (recent releases or maintained long term support versions)
•   as this may be caused by faulty drivers, keep the systems up-to-date
ROTATIONAL DISKS (HDD) Rotational HDDs typically fail at the level of individual sectors or small clusters. Read failures are caught on the levels below the filesystem and are returned to the user as EIO - Input/output error. Reading the blocks repeatedly may return the data eventually, but this is better done by specialized tools and filesystem takes the result of the lower layers. Rewriting the sectors may trigger internal remapping but this inevitably leads to data loss.
Disk firmware is technically software but from the filesystem perspective is part of the hardware. IO requests are processed, and caching or various other optimizations are performed, which may lead to bugs under high load or unexpected physical conditions or unsupported use cases.
Disks are connected by cables with two ends, both of which can cause problems when not attached properly. Data transfers are protected by checksums and the lower layers try hard to transfer the data correctly or not at all. The errors from badly-connecting cables may manifest as large amount of failed read or write requests, or as short error bursts depending on physical conditions.
•   check smartctl for potential issues
SOLID STATE DRIVES (SSD) The mechanism of information storage is different from HDDs and this affects the failure mode as well. The data are stored in cells grouped in large blocks with limited number of resets and other write constraints. The firmware tries to avoid unnecessary resets and performs optimizations to maximize the storage media lifetime. The known techniques are deduplication (blocks with same fingerprint/hash are mapped to same physical block), compression or internal remapping and garbage collection of used memory cells. Due to the additional processing there are measures to verity the data e.g. by ECC codes.
The observations of failing SSDs show that the whole electronic fails at once or affects a lot of data (eg. stored on one chip). Recovering such data may need specialized equipment and reading data repeatedly does not help as it’s possible with HDDs.
There are several technologies of the memory cells with different characteristics and price. The lifetime is directly affected by the type and frequency of data written. Writing "too much" distinct data (e.g. encrypted) may render the internal deduplication ineffective and lead to a lot of rewrites and increased wear of the memory cells.
There are several technologies and manufacturers so it’s hard to describe them but there are some that exhibit similar behaviour:
•   expensive SSD will use more durable memory cells and is optimized for reliability and high load
•   cheap SSD is projected for a lower load ("desktop user") and is optimized for cost, it may employ the optimizations and/or extended error reporting partially or not at all
It’s not possible to reliably determine the expected lifetime of an SSD due to lack of information about how it works or due to lack of reliable stats provided by the device.
Metadata writes tend to be the biggest component of lifetime writes to a SSD, so there is some value in reducing them. Depending on the device class (high end/low end) the features like DUP block group profiles may affect the reliability in both ways:
•   high end are typically more reliable and using single for data and metadata could be suitable to reduce device wear
•   low end could lack ability to identify errors so an additional redundancy at the filesystem level (checksums, DUP) could help
Only users who consume 50 to 100% of the SSD’s actual lifetime writes need to be concerned by the write amplification of btrfs DUP metadata. Most users will be far below 50% of the actual lifetime, or will write the drive to death and discover how many writes 100% of the actual lifetime was. SSD firmware often adds its own write multipliers that can be arbitrary and unpredictable and dependent on application behavior, and these will typically have far greater effect on SSD lifespan than DUP metadata. It’s more or less impossible to predict when a SSD will run out of lifetime writes to within a factor of two, so it’s hard to justify wear reduction as a benefit.
•   https://www.snia.org/educational-library/ssd-and-deduplication-end-spinning-disk-2012
•   https://www.snia.org/educational-library/realities-solid-state-storage-2013-2013
•   https://www.snia.org/educational-library/ssd-performance-primer-2013
•   https://www.snia.org/educational-library/how-controllers-maximize-ssd-life-2013
•   run smartctl or self-tests to look for potential issues
•   keep the firmware up-to-date
NVM EXPRESS, NON-VOLATILE MEMORY (NVMe) NVMe is a type of persistent memory usually connected over a system bus (PCIe) or similar interface and the speeds are an order of magnitude faster than SSD. It is also a non-rotating type of storage, and is not typically connected by a cable. It’s not a SCSI type device either but rather a complete specification for logical device interface.
In a way the errors could be compared to a combination of SSD class and regular memory. Errors may exhibit as random bit flips or IO failures. There are tools to access the internal log (nvme log and nvme-cli) for a more detailed analysis.
There are separate error detection and correction steps performed e.g. on the bus level and in most cases never making in to the filesystem level. Once this happens it could mean there’s some systematic error like overheating or bad physical connection of the device. You may want to run self-tests (using smartctl).
•   https://en.wikipedia.org/wiki/NVM_Express
•   https://www.smartmontools.org/wiki/NVMe_Support
DRIVE FIRMWARE Firmware is technically still software but embedded into the hardware. As all software has bugs, so does firmware. Storage devices can update the firmware and fix known bugs. In some cases the it’s possible to avoid certain bugs by quirks (device-specific workarounds) in Linux kernel.
A faulty firmware can cause wide range of corruptions from small and localized to large affecting lots of data. Self-repair capabilities may not be sufficient.
•   check for firmware updates in case there are known problems, note that updating firmware can be risky on itself
SD FLASH CARDS There are a lot of devices with low power consumption and thus using storage media based on low power consumption too, typically flash memory stored on a chip enclosed in a detachable card package. An improperly inserted card may be damaged by electrical spikes when the device is turned on or off. The chips storing data in turn may be damaged permanently. All types of flash memory have a limited number of rewrites, so the data are internally translated by FTL (flash translation layer). This is implemented in firmware (technically a software) and prone to bugs that manifest as hardware errors.
Adding redundancy like using DUP profiles for both data and metadata can help in some cases but a full backup might be the best option once problems appear and replacing the card could be required as well.
HARDWARE AS THE MAIN SOURCE OF FILESYSTEM CORRUPTIONS If you use unreliable hardware and don’t know about that, don’t blame the filesystem when it tells you.
acl(5), btrfs(8), chattr(1), fstrim(8), ioctl(2), mkfs.btrfs(8), mount(8), swapon(8)
PIP-INSTALL(1)                         pip                        PIP-INSTALL(1)
pip-install - description of pip install command
IMPORTANT: Did this article help?
We are currently doing research to improve pip's documentation and would love your feedback.  Please email us and let us know why you came to this page and what on it helped you and what did not.    (Read more about this research)
Install packages from:
• PyPI (and other indexes) using requirement specifiers.
• Local or remote source archives.
pip also supports installing from "requirements files", which provide an easy way to specify a whole environment to be installed.
python -m pip install [options] <requirement specifier> [package-index-options] ... python -m pip install [options] -r <requirements file> [package-index-options] ... python -m pip install [options] [-e] <vcs project url> ... python -m pip install [options] [-e] <local project path> ... python -m pip install [options] <archive url/path> ...
-r, --requirement <file> Install from the given requirements file. This option can be used multiple times.
-c, --constraint <file> Constrain versions using the given constraints file. This option can be used multiple times.
-e, --editable <path/url> Install a project in editable mode (i.e. setuptools "develop mode") from a local project path or a VCS url.
-t, --target <dir> Install packages into <dir>. By default this will not replace existing files/folders in <dir>. Use --upgrade to replace existing packages in <dir> with new versions.
--platform <platform> Only use wheels compatible with <platform>. Defaults to the platform of the running system. Use this option multiple times to specify multiple platforms supported by the target interpreter.
--python-version <python_version> The Python interpreter version to use for wheel and "Requires-Python" compatibility checks. Defaults to a version derived from the running interpreter. The version can be specified using up to three dot-separated integers (e.g. "3" for 3.0.0, "3.7" for 3.7.0, or "3.7.3"). A major-minor version can also be given as a string without dots (e.g. "37" for 3.7.0).
--implementation <implementation> Only use wheels compatible with Python implementation <implementation>, e.g. 'pp', 'jy', 'cp',  or 'ip'. If not specified, then the current interpreter implementation is used. Use 'py' to force implementation-agnostic wheels.
--abi <abi> Only use wheels compatible with Python abi <abi>, e.g. 'pypy_41'. If not specified, then the current interpreter abi tag is used. Use this option multiple times to specify multiple abis supported by the target interpreter. Generally you will need to specify --implementation, --platform, and --python-version when using this option.
--user Install to the Python user install directory for your platform. Typically ~/.local/, or %APPDATA%Python on Windows. (See the Python documentation for site.USER_BASE for full details.)
--prefix <dir> Installation prefix where lib, bin and other top-level folders are placed
--src <dir> Directory to check out editable projects into. The default in a virtualenv is "<venv path>/src". The default for global installs is "<current dir>/src".
-U, --upgrade Upgrade all specified packages to the newest available version. The handling of dependencies depends on the upgrade-strategy used.
--upgrade-strategy <upgrade_strategy> Determines how dependency upgrading should be handled [default: only-if-needed]. "eager" - dependencies are upgraded regardless of whether the currently installed version satisfies the requirements of the upgraded package(s). "only-if-needed" -  are upgraded only when they do not satisfy the requirements of the upgraded package(s).
--force-reinstall Reinstall all packages even if they are already up-to-date.
-I, --ignore-installed Ignore the installed packages, overwriting them. This can break your system if the existing package is of a different version or was installed with a different package manager!
--ignore-requires-python Ignore the Requires-Python information.
--no-build-isolation Disable isolation when building a modern source distribution. Build dependencies specified by PEP 518 must be already installed if this option is used.
--use-pep517 Use PEP 517 for building source distributions (use --no-use-pep517 to force legacy behaviour).
--install-option <options> Extra arguments to be supplied to the setup.py install command (use like --install-option="--install-scripts=<sys.prefix>/local/bin"). Use multiple --install-option options to pass multiple options to setup.py install. If you are using an option with a directory path, be sure to use absolute path.
--compile Compile Python source files to bytecode
--no-compile Do not compile Python source files to bytecode
--no-warn-script-location Do not warn when installing scripts outside PATH
--no-warn-conflicts Do not warn about broken dependencies
--no-binary <format_control> Do not use binary packages. Can be supplied multiple times, and each time adds to the existing value. Accepts either ":all:" to disable all binary packages, ":none:" to empty the set (notice the colons), or one or more package names with commas between them (no colons). Note that some packages are tricky to compile and may fail to install when this option is used on them.
--only-binary <format_control> Do not use source packages. Can be supplied multiple times, and each time adds to the existing value. Accepts either ":all:" to disable all source packages, ":none:" to empty the set, or one or more package names with commas between them. Packages without binary distributions will fail to install when this option is used on them.
--prefer-binary Prefer older binary packages over newer source packages.
--require-hashes Require a hash to check each requirement against, for repeatable installs. This option is implied when any package in a requirements file has a --hash option.
--progress-bar <progress_bar> Specify type of progress to be displayed [off|on|ascii|pretty|emoji] (default: on)
We are currently doing research to improve pip's documentation and would love your feedback.  Please email us and let us know:
1. What problem were you trying to solve when you came to this page?
2. What content was useful?
3. What content was not useful?
pip developers
2008-2021, PyPA
RUBY(1)                 Ruby Programmer's Reference Guide                RUBY(1)
ruby — Interpreted object-oriented scripting language
ruby [--copyright] [--version] [-SUacdlnpswvy] [-0[octal]] [-C directory] [-E external[:internal]] [-F[pattern]] [-I directory] [-K[c]] [-T[level]] [-W[level]] [-e command] [-i[extension]] [-r library] [-x[directory]] [--{enable|disable}-FEATURE] [--dump=target] [--verbose] [--] [program_file] [argument ...]
Ruby is an interpreted scripting language for quick and easy object- oriented programming.  It has many features to process text files and to do system management tasks (like in Perl).  It is simple, straight-forward, and extensible.
If you want a language for easy object-oriented programming, or you don't like the Perl ugliness, or you do like the concept of LISP, but don't like too many parentheses, Ruby might be your language of choice.
Ruby's features are as follows:
Interpretive Ruby is an interpreted language, so you don't have to recompile programs written in Ruby to execute them.
Variables have no type (dynamic typing) Variables in Ruby can contain data of any type.  You don't have to worry about variable typing.  Consequently, it has a weaker compile time check.
No declaration needed You can use variables in your Ruby programs without any declarations.  Variable names denote their scope - global, class, instance, or local.
Simple syntax Ruby has a simple syntax influenced slightly from Eiffel.
No user-level memory management Ruby has automatic memory management.  Objects no longer referenced from anywhere are automatically collected by the garbage collector built into the interpreter.
Everything is an object Ruby is a purely object-oriented language, and was so since its creation.  Even such basic data as integers are seen as objects.
Class, inheritance, and methods Being an object-oriented language, Ruby naturally has basic features like classes, inheritance, and methods.
Singleton methods Ruby has the ability to define methods for certain objects.  For example, you can define a press-button action for certain widget by defining a singleton method for the button.  Or, you can make up your own prototype based object system using singleton methods, if you want to.
Mix-in by modules Ruby intentionally does not have the multiple inheritance as it is a source of confusion.  Instead, Ruby has the ability to share implementations across the inheritance tree.  This is often called a ‘Mix-in’.
Iterators Ruby has iterators for loop abstraction.
Closures In Ruby, you can objectify the procedure.
Text processing and regular expressions Ruby has a bunch of text processing features like in Perl.
M17N, character set independent Ruby supports multilingualized programming. Easy to process texts written in many different natural languages and encoded in many different character encodings, without dependence on Unicode.
Bignums With built-in bignums, you can for example calculate factorial(400).
Reflection and domain specific languages Class is also an instance of the Class class. Definition of classes and methods is an expression just as 1+1 is. So your programs can even write and modify programs.  Thus you can write your application in your own programming language on top of Ruby.
Exception handling As in Java(tm).
Direct access to the OS Ruby can use most UNIX system calls, often used in system programming.
Dynamic loading On most UNIX systems, you can load object files into the Ruby interpreter on-the-fly.
Rich libraries In addition to the “builtin libraries” and “standard libraries” that are bundled with Ruby, a vast amount of third-party libraries (“gems”) are available via the package management system called ‘RubyGems’, namely the gem(1) command.  Visit RubyGems.org (https://rubygems.org/) to find the gems you need, and explore GitHub (https://github.com/) to see how they are being developed and used.
The Ruby interpreter accepts the following command-line options (switches). They are quite similar to those of perl(1).
--copyright    Prints the copyright notice, and quits immediately without running any script.
--version      Prints the version of the Ruby interpreter, and quits immediately without running any script.
-0[octal]      (The digit “zero”.)  Specifies the input record separator ($/) as an octal number. If no digit is given, the null character is taken as the separator.  Other switches may follow the digits.  -00 turns Ruby into paragraph mode. -0777 makes Ruby read whole file at once as a single string since there is no legal character with that value.
-C directory -X directory   Causes Ruby to switch to the directory.
-E external[:internal] --encoding external[:internal] Specifies the default value(s) for external encodings and internal encoding. Values should be separated with colon (:).
You can omit the one for internal encodings, then the value (Encoding.default_internal) will be nil.
--external-encoding=encoding --internal-encoding=encoding Specify the default external or internal character encoding
-F pattern     Specifies input field separator ($;).
-I directory   Used to tell Ruby where to load the library scripts. Directory path will be added to the load-path variable ($:).
-K kcode       Specifies KANJI (Japanese) encoding. The default value for script encodings (__ENCODING__) and external encodings (Encoding.default_external) will be the specified one. kcode can be one of
e       EUC-JP
s       Windows-31J (CP932)
u       UTF-8
n       ASCII-8BIT (BINARY)
-S             Makes Ruby use the PATH environment variable to search for script, unless its name begins with a slash.  This is used to emulate #! on machines that don't support it, in the following manner:
#! /usr/local/bin/ruby # This line makes the next one a comment in Ruby \ exec /usr/local/bin/ruby -S $0 $*
On some systems $0 does not always contain the full pathname, so you need the -S switch to tell Ruby to search for the script if necessary (to handle embedded spaces and such).  A better construct than $* would be ${1+"$@"}, but it does not work if the script is being interpreted by csh(1).
-T[level=1]    Turns on taint checks at the specified level (default 1).
-U             Sets the default value for internal encodings (Encoding.default_internal) to UTF-8.
-W[level=2]    Turns on verbose mode at the specified level without printing the version message at the beginning. The level can be;
0       Verbose mode is "silence". It sets the $VERBOSE to nil.
1       Verbose mode is "medium". It sets the $VERBOSE to false.
2 (default) Verbose mode is "verbose". It sets the $VERBOSE to true.  -W2 is same as -w
-a             Turns on auto-split mode when used with -n or -p.  In auto- split mode, Ruby executes $F = $_.split at beginning of each loop.
-c             Causes Ruby to check the syntax of the script and exit without executing. If there are no syntax errors, Ruby will print “Syntax OK” to the standard output.
-d --debug        Turns on debug mode.  $DEBUG will be set to true.
-e command     Specifies script from command-line while telling Ruby not to search the rest of the arguments for a script file name.
-h --help         Prints a summary of the options.
-i extension   Specifies in-place-edit mode.  The extension, if specified, is added to old file name to make a backup copy.  For example:
% echo matz > /tmp/junk % cat /tmp/junk matz % ruby -p -i.bak -e '$_.upcase!' /tmp/junk % cat /tmp/junk MATZ % cat /tmp/junk.bak matz
-l             (The lowercase letter “ell”.)  Enables automatic line-ending processing, which means to firstly set $\ to the value of $/, and secondly chops every line read using chomp!.
-n             Causes Ruby to assume the following loop around your script, which makes it iterate over file name arguments somewhat like sed -n or awk.
while gets ... end
-p             Acts mostly same as -n switch, but print the value of variable $_ at the each end of the loop.  For example:
% echo matz | ruby -p -e '$_.tr! "a-z", "A-Z"' MATZ
-r library     Causes Ruby to load the library using require.  It is useful when using -n or -p.
-s             Enables some switch parsing for switches after script name but before any file name arguments (or before a --).  Any switches found there are removed from ARGV and set the corresponding variable in the script.  For example:
#! /usr/local/bin/ruby -s # prints "true" if invoked with `-xyz' switch. print "true\n" if $xyz
-v             Enables verbose mode.  Ruby will print its version at the beginning and set the variable $VERBOSE to true.  Some methods print extra messages if this variable is true.  If this switch is given, and no other switches are present, Ruby quits after printing its version.
-w             Enables verbose mode without printing version message at the beginning.  It sets the $VERBOSE variable to true.
-x[directory]  Tells Ruby that the script is embedded in a message. Leading garbage will be discarded until the first line that starts with “#!” and contains the string, “ruby”.  Any meaningful switches on that line will be applied.  The end of the script must be specified with either EOF, ^D (control-D), ^Z (control-Z), or the reserved word __END__. If the directory name is specified, Ruby will switch to that directory before executing script.
-y --yydebug      DO NOT USE.
Turns on compiler debug mode.  Ruby will print a bunch of internal state messages during compilation.  Only specify this switch you are going to debug the Ruby interpreter.
--disable-FEATURE --enable-FEATURE Disables (or enables) the specified FEATURE. --disable-gems --enable-gems      Disables (or enables) RubyGems libraries. By default, Ruby will load the latest version of each installed gem. The Gem constant is true if RubyGems is enabled, false if otherwise.
--disable-rubyopt --enable-rubyopt   Ignores (or considers) the RUBYOPT environment variable. By default, Ruby considers the variable.
--disable-all --enable-all       Disables (or enables) all features.
--dump=target  Dump some information.
Prints the specified target.  target can be one of;
version version description same as --version
usage   brief usage message same as -h
help    Show long help message same as --help
syntax  check of syntax same as -c --yydebug
yydebug compiler debug mode, same as --yydebug
Only specify this switch if you are going to debug the Ruby interpreter.
parsetree_with_comment AST nodes tree
insns   disassembled instructions
--verbose      Enables verbose mode without printing version message at the beginning.  It sets the $VERBOSE variable to true.  If this switch is given, and no script arguments (script file or -e options) are present, Ruby quits immediately.
RUBYLIB    A colon-separated list of directories that are added to Ruby's library load path ($:). Directories from this environment variable are searched before the standard load path is searched.
e.g.: RUBYLIB="$HOME/lib/ruby:$HOME/lib/rubyext"
RUBYOPT    Additional Ruby options.
e.g. RUBYOPT="-w -Ke"
Note that RUBYOPT can contain only -d, -E, -I, -K, -r, -T, -U, -v, -w, -W, --debug, --disable-FEATURE and --enable-FEATURE.
RUBYPATH   A colon-separated list of directories that Ruby searches for Ruby programs when the -S flag is specified.  This variable precedes the PATH environment variable.
RUBYSHELL  The path to the system shell command.  This environment variable is enabled for only mswin32, mingw32, and OS/2 platforms.  If this variable is not defined, Ruby refers to COMSPEC.
PATH       Ruby refers to the PATH environment variable on calling Kernel#system.
And Ruby depends on some RubyGems related environment variables unless RubyGems is disabled.  See the help of gem(1) as below.
% gem help
The Ruby garbage collector (GC) tracks objects in fixed-sized slots, but each object may have auxiliary memory allocations handled by the malloc family of C standard library calls ( malloc(3), calloc(3), and realloc(3)). In this documentatation, the "heap" refers to the Ruby object heap of fixed-sized slots, while "malloc" refers to auxiliary allocations commonly referred to as the "process heap".  Thus there are at least two possible ways to trigger GC:
1       Reaching the object limit.
2       Reaching the malloc limit.
In Ruby 2.1, the generational GC was introduced and the limits are divided into young and old generations, providing two additional ways to trigger a GC:
3       Reaching the old object limit.
4       Reaching the old malloc limit.
There are currently 4 possible areas where the GC may be tuned by the following 11 environment variables: RUBY_GC_HEAP_INIT_SLOTS                Initial allocation slots. Introduced in Ruby 2.1, default: 10000.
RUBY_GC_HEAP_FREE_SLOTS                Prepare at least this amount of slots after GC.  Allocate this number slots if there are not enough slots.  Introduced in Ruby 2.1, default: 4096
RUBY_GC_HEAP_GROWTH_FACTOR             Increase allocation rate of heap slots by this factor.  Introduced in Ruby 2.1, default: 1.8, minimum: 1.0 (no growth)
RUBY_GC_HEAP_GROWTH_MAX_SLOTS          Allocation rate is limited to this number of slots, preventing excessive allocation due to RUBY_GC_HEAP_GROWTH_FACTOR. Introduced in Ruby 2.1, default: 0 (no limit)
RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR    Perform a full GC when the number of old objects is more than R * N, where R is this factor and N is the number of old objects after the last full GC.  Introduced in Ruby 2.1.1, default: 2.0
RUBY_GC_MALLOC_LIMIT                   The initial limit of young generation allocation from the malloc-family.  GC will start when this limit is reached.  Default: 16MB
RUBY_GC_MALLOC_LIMIT_MAX               The maximum limit of young generation allocation from malloc before GC starts.  Prevents excessive malloc growth due to RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR. Introduced in Ruby 2.1, default: 32MB.
RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR     Increases the limit of young generation malloc calls, reducing GC frequency but increasing malloc growth until RUBY_GC_MALLOC_LIMIT_MAX is reached. Introduced in Ruby 2.1, default: 1.4, minimum: 1.0 (no growth)
RUBY_GC_OLDMALLOC_LIMIT                The initial limit of old generation allocation from malloc, a full GC will start when this limit is reached.  Introduced in Ruby 2.1, default: 16MB
RUBY_GC_OLDMALLOC_LIMIT_MAX            The maximum limit of old generation allocation from malloc before a full GC starts.  Prevents excessive malloc growth due to RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR. Introduced in Ruby 2.1, default: 128MB
RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR  Increases the limit of old generation malloc allocation, reducing full GC frequency but increasing malloc growth until RUBY_GC_OLDMALLOC_LIMIT_MAX is reached.  Introduced in Ruby 2.1, default: 1.2, minimum: 1.0 (no growth)
Stack size environment variables are implementation-dependent and subject to change with different versions of Ruby.  The VM stack is used for pure- Ruby code and managed by the virtual machine.  Machine stack is used by the operating system and its usage is dependent on C extensions as well as C compiler options.  Using lower values for these may allow applications to keep more Fibers or Threads running; but increases the chance of SystemStackError exceptions and segmentation faults (SIGSEGV).  These environment variables are available since Ruby 2.0.0.  All values are specified in bytes.
RUBY_THREAD_VM_STACK_SIZE       VM stack size used at thread creation. default: 131072 (32-bit CPU) or 262144 (64-bit)
RUBY_THREAD_MACHINE_STACK_SIZE  Machine stack size used at thread creation. default: 524288 or 1048575
RUBY_FIBER_VM_STACK_SIZE        VM stack size used at fiber creation. default: 65536 or 131072
RUBY_FIBER_MACHINE_STACK_SIZE   Machine stack size used at fiber creation. default: 262144 or 524288
https://www.ruby-lang.org/     The official web site. https://www.ruby-toolbox.com/  Comprehensive catalog of Ruby libraries.
•   Security vulnerabilities should be reported via an email to security@ruby-lang.org.  Reported problems will be published after being fixed.
•   Other bugs and feature requests can be reported via the Ruby Issue Tracking System (https://bugs.ruby-lang.org/). Do not report security vulnerabilities via this system because it publishes the vulnerabilities immediately.
Ruby is designed and implemented by Yukihiro Matsumoto <matz@netlab.jp>.
See ⟨https://bugs.ruby-lang.org/projects/ruby/wiki/Contributors⟩ for contributors to Ruby.
PYTHON(1)                    General Commands Manual                   PYTHON(1)
python - an interpreted, interactive, object-oriented programming language
python [ -B ] [ -b ] [ -d ] [ -E ] [ -h ] [ -i ] [ -I ] [ -m module-name ] [ -q ] [ -O ] [ -OO ] [ -s ] [ -S ] [ -u ] [ -v ] [ -V ] [ -W argument ] [ -x ] [ [ -X option ] -?  ] [ --check-hash-based-pycs default | always | never ] [ -c command | script | - ] [ arguments ]
Python is an interpreted, interactive, object-oriented programming language that combines remarkable power with very clear syntax.  For an introduction to programming in Python, see the Python Tutorial.  The Python Library Reference documents built-in and standard types, constants, functions and modules.  Finally, the Python Reference Manual describes the syntax and semantics of the core language in (perhaps too) much detail.  (These documents may be located via the INTERNET RESOURCES below; they may be installed on your system as well.)
Python's basic power can be extended with your own modules written in C or C++.  On most systems such modules may be dynamically loaded.  Python is also adaptable as an extension language for existing applications. See the internal documentation for hints.
Documentation for installed Python modules and packages can be viewed by running the pydoc program.
-B     Don't write .pyc files on import. See also PYTHONDONTWRITEBYTECODE.
-b     Issue warnings about str(bytes_instance), str(bytearray_instance) and comparing bytes/bytearray with str. (-bb: issue errors)
-c command Specify the command to execute (see next section).  This terminates the option list (following options are passed as arguments to the command).
--check-hash-based-pycs mode Configure how Python evaluates the up-to-dateness of hash-based .pyc files.
-d     Turn on parser debugging output (for expert only, depending on compilation options).
-E     Ignore environment variables like PYTHONPATH and PYTHONHOME that modify the behavior of the interpreter.