I am using dd to return a stream of data from tape. I want to send this via a pipe that will extract the byte range I require. I need to check for the presence of a string in the initial bytes, and based on that value the byte range will differ. Something like this...

dd if=/dev/tape/st0 bs=512K | { var=1; if [[ $(head -c13) == "././@LongLink" ]]; then var=3; } | dd of=extracted_file.bin skip=$(512*$var) iflag=skip_bytes

However, I understand that a variable cannot be referenced after the pipe segment in which it is defined.


Based on kusalananda's comment, I think the best way to achieve may actual goal is to restore a single block from the tape, get the info I need, then rewind and restore the whole file using dd and the calculated value for skip. This is because there doesn't seem to be any reliable way to remove bytes from the beginning of a file inplace (unlike for the end, where we have truncate)


1 Answer 1


Consider the following untested code:

dd if=/dev/tape/st0 bs=512K |
    if [[ $( head -c 13 ) == "././@LongLink" ]]; then
        skip=$(( skip*3 ))
    dd of=extracted_file.bin skip="$skip" iflag=skip_bytes

This passes the data from the initial dd into a compound command. The compound command sets skip (I renamed your variable) to some number and calls dd. The second dd will read from standard input, which is inherited from the compound command, which gets it from the initial dd.

Note that the second dd will not see the data read by the head call! Also, some head implementations may read more data than requested, which may cause the second dd to see too little data. GNU head (which is what you're using here) seems to be well behaved in this respect.

  • dd has skip and count, but you need to know ahead of time to generate the proper command line. Jun 5, 2020 at 14:42
  • @AaronD.Marasco I only address the actual issue in the question, i.e. how a variable may be used as part of a stage in a pipeline. If the dd commands works or not, I have no way of testing. Mostly because I don't use a Unix where the dd command takes the parameters used in the code.
    – Kusalananda
    Jun 5, 2020 at 14:47
  • @kusalananda could we read a block of 512 bytes assign the variable, and then write the same block to stdout, so that the 2nd dd command sees all the data?
    – swami
    Jun 5, 2020 at 14:48
  • @swami Update your question with your requirements. I may delete this answer if I feel I can't address those requirements.
    – Kusalananda
    Jun 5, 2020 at 14:50
  • 1
    @swami Well, one solution would be to read the first bit of the tape, set the variable conditionally, rewind, and then do a simpler pipeline.
    – Kusalananda
    Jun 5, 2020 at 15:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .