به طور اساسی پاسخ خیر است....
در حالیکه bash مشکلاتی به زیادی پوستههای قدیمیتر با آنها ندارد، باز هم نمیتواند دادههای باینری اختیاری را پردازش نماید، و به طور اخص، متغیرهای پوسته 100% باینری خالص نیستند، بنابراین نمیتوانید فایلهای باینری را در آنها ذخیره کنید.
شما میتوانید دادههای اسکی کُدگذاری شده یونیکس به یونیکس(uuencoded) را به این طریق در متغییر قرار دهید:
var=$(uuencode /bin/ls ls) cd /somewhere/else uudecode <<<"$var" # نقلقولها را فراموش نکنید
توجه: تفاوت سترگی میان uuencode یا uudecode گنو و یونیکس وجود دارد. با uudecode یونیکس، شما نمیتوانید فایل خروجی تعیین کنید، همواره از نام فایل کدگذاری شده در داده اسکی استفاده میکند. من مثال قبلی را اصلاح کردهام به طوری که در سیستمهای یونیکس کار میکند. اگر شما تغییرات بیشتری ایجاد میکنید، لطفاً رویهگرایی گنو (GNUisms) را به کار نبرید. متشکرم. --GreyCat
یک نمونه که چنین موردی ممکن است گاهی در آن سودمند باشد، ذخیره کردن نقشهبیتیهای کوچک موقتی، در هنگام کار کردن با netpbm است... در اینجا من به یک pnmnoraw زیرنویس 1 اضافی در لوله متوسل شدم که باعث ایجاد فایلهای اسکی بزرگتر میشود و bash با ذخیره آنها مشکلی ندارد.
اگر احساس ماجراجویی دارید، این تجربه را ملاحظه نمایید:
# bindec.bash, سعی میکند دادههای باینری را به اسکی دسیمال رمزگشایی کند IFS= while read -n1 x ;do case "$x" in '') echo empty ;; # ۲۵۶ سطر تولید شده توسط سطر فرمان زیر را در اینجا درج کنید # for x in $(seq 0 255) ;do echo " $'\\$(printf %o $x)') echo $x;;" ;done esac done
و سپس داده باینری را به آن لولهکشی کنید، شاید اینطور :
for x in $(seq 0 255) ;do echo -ne "\\$(printf %o $x)" ;done | bash bindec.bash | nl | less
این کد ایجاب میکند که کاراکتر 0 به طور کلی از قلم انداخته شود، زیرا ما نمیتوانیم آنرا با تولید کننده ورودی ایجاد کنیم، به راحتی برای خراب کردن اکثر فایلهای باینری که میخواهیم پردازش کنیم، کفایت میکند.
بلی، Bash به زبان C نوشته شده، و از معناشناسی این زبان برای مدیریت رشتهها -- شامل بایتهای NUL به عنوان حدفاصل رشتهها -- در متغیرهایش استفاده میکند. شما نمیتوانید به طور معقولی NUL را در متغیرهای Bash ذخیره نمایید. در حقیقت هرگز هم قرار نبوده به این صورت به کار برود. - GreyCat
توجه نمایید که این مطلب اشاره به نگهداری آنها در متغیرها دارد... انتقال دادهها بین برنامهها با استفاده از لولهها همیشه باینری بدون عیب است. فایلهای موقتی نیز به شرطی که موقع ایجاد آنها اقدامات احتیاطی متناسب انجام بشود، بیخطر هستند.
برای cat کردن فایل باینری تنها با دستورات داخلی bash موقعی که برنامه خارجی در دسترس نباشد(یکبار وقتی نام فایل /lib/libgcc_s.so.1 تغییر کرده بود، استفاده از این ترفند کارم را راه انداخت):
# باینری مطمئن bash فقط با دستورات داخلی cat شبیهسازی IFS= while read -d '' -r -n1 x ; do case "$x" in '') printf "\x00";; *) printf "%s" "$x";; esac done
من ترجیح خواهم داد از cat استفاده کنم. همچنین، آن -n1 واقعاً لازم بود؟ -GreyCat
بدون -n1 شما باید برای کار کردن با دادههای بعد از آخرین \0 خیلی با احتیاط باشید، موردی مانند این [[ $x ]] && printf "%s" "%x" بعد از حلقه. من این را بررسی نکردهام که بدانم آیا کار میکند یا اینکه کافی هست. همچنین من نمیدانم اگر شما یک فایل بزرگ بدون هیچ \0 را بخوانید چه اتفاقی میافتد --pgas
پرسش و پاسخ 58 (آخرین ویرایش 2009-03-09 08:26:26 توسط pgas)