relpipe-data/examples-out-bash.xml
branchv_0
changeset 244 d4f401b5f90c
parent 241 f71d300205b7
child 290 e73765513aec
equal deleted inserted replaced
243:9c1d0c5ed599 244:d4f401b5f90c
       
     1 <stránka
       
     2 	xmlns="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/strana"
       
     3 	xmlns:m="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/makro">
       
     4 	
       
     5 	<nadpis>Writing an output filter in Bash</nadpis>
       
     6 	<perex>processing relational data in GNU Bash or some other shell</perex>
       
     7 	<m:pořadí-příkladu>00600</m:pořadí-příkladu>
       
     8 
       
     9 	<text xmlns="http://www.w3.org/1999/xhtml">
       
    10 		
       
    11 		<p>
       
    12 			In previous example we created an output filter in Perl. 
       
    13 			We converted a relation to values separated by <code>\0</code> and then passed it through <code>xargs</code> to a perl <em>one-liner</em> (or a <em>multi-liner</em> in this case).
       
    14 			But we can write such output filter in pure Bash without <code>xargs</code> and <code>perl</code>.
       
    15 			Of course, it is still limited to a single relation (or it can process multiple relations of same type and do something like implicit <code>UNION ALL</code>).
       
    16 		</p>
       
    17 		
       
    18 		<p>
       
    19 			We will define a function that will help us with reading the <code>\0</code>-separated values and putting them into shell variables:
       
    20 		</p>
       
    21 		
       
    22 		<m:pre jazyk="bash"><![CDATA[read_nullbyte() { for v in "$@"; do export "$v"; read -r -d '' "$v"; done }]]></m:pre>
       
    23 		
       
    24 		<!--
       
    25 			This version will not require the last \0:
       
    26 				read_zero() { for v in "$@"; do export "$v"; read -r -d '' "$v" || [ ! -z "${!v}" ]; done }
       
    27 			at least in case when the last value is not missing.
       
    28 			Other values might be null/missing: \0\0 is OK.
       
    29 		-->
       
    30 		
       
    31 		<p>
       
    32 			Currently, there is no known way how to do this without a custom function (just with <code>read</code> built-in command of Bash and its parameters).
       
    33 			But it is just a single line function, so not a big deal.
       
    34 		</p>
       
    35 		
       
    36 		<p>
       
    37 			And then we just read the values, put them in shell variables and process them in a cycle in a shell block of code:
       
    38 		</p>
       
    39 		
       
    40 		<m:pre jazyk="bash"><![CDATA[relpipe-in-fstab \
       
    41 	| relpipe-out-nullbyte \
       
    42 	| while read_nullbyte scheme device mount_point fs_type options dump pass; do
       
    43 		echo "Device ${scheme:+$scheme=}$device is mounted" \
       
    44 		     "at $mount_point and contains $fs_type.";
       
    45 	done]]></m:pre>
       
    46 	
       
    47 		<p>
       
    48 			Which will print:
       
    49 		</p>
       
    50 		
       
    51 		<pre><![CDATA[Device UUID=29758270-fd25-4a6c-a7bb-9a18302816af is mounted at / and contains ext4.
       
    52 Device /dev/sr0 is mounted at /media/cdrom0 and contains udf,iso9660.
       
    53 Device /dev/sde is mounted at /mnt/data and contains ext4.
       
    54 Device UUID=a2b5f230-a795-4f6f-a39b-9b57686c86d5 is mounted at /home and contains btrfs.
       
    55 Device /dev/mapper/sdf_crypt is mounted at /mnt/private and contains xfs.]]></pre>
       
    56 
       
    57 		<p>
       
    58 			Using this method, we can convert any single relation to any format (preferably some text one, but <code>printf</code> can produce also binary data).
       
    59 			This is good for ad-hoc conversions and single-relation data.
       
    60 			More powerful tools can be written in C++ and other languages like Java, Python, Guile etc. (when particular libraries are available).
       
    61 		</p>
       
    62 		
       
    63 	</text>
       
    64 
       
    65 </stránka>