ব্যাশ চলকগুলিতে 0x00 হেক্সভ্যালু সংরক্ষণ করতে পারে না


11

আমি ডিডির সাথে কিছু কৌশল করার চেষ্টা করছি। আমি ভেবেছিলাম এটির ডিডি-তে পাইপ দেওয়ার জন্য "হেডার" নামক একটি ভেরিয়েবলে কিছু হেক্সভ্যালু সংরক্ষণ করা সম্ভব হবে।

পরিবর্তনশীল ব্যতীত আমার প্রথম পদক্ষেপটি ছিল:

$ echo -ne "\x36\xc9\xda\x00\xb4" |dd of=hex
$ hd hex

00000000  36 c9 da 00 b4                                    |6....|
00000005

এর পরে আমি এটি চেষ্টা করেছি:

$ header=$(echo -ne "\x36\xc9\xda\x00\xb4") 
$ echo -n $header | hd

00000000  36 c9 da b4                                       |6...|
00000004

আপনি দেখতে পাচ্ছেন যে আমি ভেরিয়েবলে আমার \x00মানটি হারিয়েছি $header। কারও কি এই আচরণের ব্যাখ্যা আছে? এটি আমাকে উন্মাদ করে দিচ্ছে।


আমি পেতে bash: warning: command substitution: ignored null byte in input
কুসালানন্দ

আপনার উদ্ধৃতিগুলি নিখোঁজ রয়েছে এটি হওয়া উচিত header="$(echo -ne "\x36\xc9\xda\x00\xb4")"; echo -n "$header" | hdতবে এটি কেবল একই ফলাফল দেয়।
ctrl-alt-delor

এটি কাজ করে header="\x36\xc9\xda\x00\xb4"; echo -n "$header" | hdতবে এটি মানব পাঠযোগ্য ফর্মটি সংরক্ষণ করার মতো জিনিস নয়।
ctrl-alt-delor

উত্তর:


16

আপনি স্ট্রিংয়ে নাল বাইট সংরক্ষণ করতে পারবেন না কারণ বাশ সি-স্টাইলের স্ট্রিং ব্যবহার করে, যা টার্মিনেটরগুলির জন্য নাল বাইট সংরক্ষণ করে। সুতরাং আপনার স্ক্রিপ্টটি পুনরায় লেখার জন্য কেবল বাশকে মাঝখানে সঞ্চয় করার প্রয়োজন ছাড়াই নাল বাইট রয়েছে এমন ক্রমটি পাইপ করতে হবে। উদাহরণস্বরূপ, আপনি এটি করতে পারেন:

printf "\x36\xc9\xda\x00\xb4" | hd

খেয়াল করুন, উপায় দ্বারা, আপনার প্রয়োজন নেই echo; আপনি এর printfজন্য আরও অনেক সাধারণ কাজের জন্য বাশের ব্যবহার করতে পারেন ।

বা শৃঙ্খলার পরিবর্তে আপনি একটি অস্থায়ী ফাইল ব্যবহার করতে পারেন:

printf "\x36\xc9\xda\x00\xb4" > /tmp/mysequence
hd /tmp/mysequence

অবশ্যই, এটিতে সমস্যা রয়েছে যে ফাইলটি /tmp/mysequenceইতিমধ্যে থাকতে পারে। এবং এখন আপনার অস্থায়ী ফাইলগুলি তৈরি করা এবং স্ট্রিংগুলিতে তাদের পাথ সংরক্ষণ করা প্রয়োজন।

বা প্রক্রিয়া প্রতিস্থাপন ব্যবহার করে আপনি এড়াতে পারেন:

hd <(printf "\x36\xc9\xda\x00\xb4")

<(command)অপারেটর ফাইল সিস্টেমে একটি নামে নল, যা আউটপুট পাবেন সৃষ্টি commandhdএটির প্রথম যুক্তি হিসাবে, পাইপটির পাথ পাবে it এটি প্রায় কোনও ফাইলের মতোই খোলা এবং পড়বে । আপনি এটি সম্পর্কে এখানে আরও পড়তে পারেন: /unix//a/17117/136742


1
সঠিক হওয়ার পরেও এটি বাস্তবায়নের বিশদ এবং সঠিক কারণ নয়। আমি এটি দেখেছিলাম, এবং পসিক্স স্ট্যান্ডার্ডটির আসলে এই আচরণটি প্রয়োজন , সুতরাং সেখানে আপনার আসল কারণ রয়েছে। (যেমন কেউ কেউ নির্দেশ করেছেন, zshএটি করবেন, তবে এটি কেবলমাত্র প্যানিক্স মোডে)) আমি আসলে এটি দেখেছিলাম কারণ আমি ভাবছিলাম যে এটি কার্যকর করার জন্য এটি উপযুক্ত কিনা mksh...
মিরাবিলোস

@ মিরাবিলোস, আপনি কি এর উপর প্রসারিত করার যত্ন নেবেন? আফিকা, কমান্ড প্রতিস্থাপনের জন্য আউটপুটটিতে NU টি অক্ষর থাকে এবং POSIX মোডে zsh এর জন্য, আচরণের ক্ষেত্রে POSIX অনুযায়ী অনির্দিষ্ট করা হয়, কেবলমাত্র প্রাসঙ্গিক পার্থক্য যা আমি shঅনুকরণ করতে পারি \0তা হ'ল ডিফল্ট মান নয় $IFSecho "$(printf 'a\0b')"এখনও shঅনুকরণে ঠিক আছে কাজ করে zsh
স্টাফেন চেজেলাস

3
@ মিরাবিলোস বিবেচনা করে যে শেলগুলি পসিক্স স্ট্যান্ডার্ডকে এক দশক বা তারও বেশি সময় ধরে পূর্বে দেয়, আমি অনুমান করি যে আসল আসল কারণ হ'ল শেলগুলি সি-স্টাইলের স্ট্রিং ব্যবহার করেছিল এবং স্ট্যান্ডার্ডটি চারপাশে নির্মিত হয়েছিল।
giyti

প্রিন্টফ বনাম প্রতিধ্বনি সম্পর্কে বিস্তারিত আলোচনার জন্য আমি একটি ভাল প্রশ্ন পেয়েছি। unix.stackexchange.com/questions/65803/…
পলব

8

আপনি zshপরিবর্তে এটি ব্যবহার করতে পারেন যা কেবলমাত্র শেল যা নুল অক্ষরটিকে তার ভেরিয়েবলগুলিতে সঞ্চয় করতে পারে। যে চরিত্র এমনকি ডিফল্ট মান হতে হবে $IFSমধ্যে zsh

nul=$'\0'

বা:

nul=$'\x0'

অথবা

nul=$'\u0000'

অথবা

nul=$(printf '\0')

তবে নোট করুন যে আপনি আর্গুমেন্ট বা পরিবেশের পরিবর্তনশীল হিসাবে কোনও আর্গুমেন্টকে একটি কমান্ডের মধ্যে যেমন আর্গুমেন্ট এবং এনভায়রনমেন্ট ভেরিয়েবলগুলি কার্যকর করা হয় সেগুলি NU- ডিলিমিটেড স্ট্রিংগুলি execve()সিস্টেম কলটিতে পাস করা হয় (সিস্টেমের API এর একটি সীমাবদ্ধতা, শেল নয়) )। ইন zsh, আপনি তবে NU বাইটগুলি ফাংশন বা বিল্টিন কমান্ডের আর্গুমেন্ট হিসাবে পাস করতে পারেন।

echo $'\0' # works
/bin/echo $'\0' # doesn't

1
"আপনি এর পরিবর্তে zsh ব্যবহার করতে পারেন"। ধন্যবাদ নেই - আমি এখনই নিজেকে শিক্ষানবিশ হিসাবে বাশ-স্ক্রিপ্টিং শিখছি। আমি নিজেকে অন্য সিনট্যাক্সের সাথে বিভ্রান্ত করতে চাই না। তবে আপনাকে এটির পরামর্শ দেওয়ার জন্য অনেক ধন্যবাদ
ফ্রাঙ্ক

প্রকৃতপক্ষে, আপনি zshআপনার প্রশ্নে বাক্য গঠন ব্যবহার করেছেন । echo -n $headerবিষয়বস্তুর পাস মানে $headerশেষ আর্গুমেন্ট হিসাবে পরিবর্তনশীল echo -nহয় zsh(অথবা fishবা rcবা es) সিনট্যাক্স না bash সিনট্যাক্স। ইন bash, এর একটি খুব আলাদা অর্থ রয়েছে । আরো সাধারণভাবে zshভালো হয় ksh( bash, গনুহ শেল, বেশী বা এর একটি অংশ-ক্লোন কম হচ্ছে ksh, ইউনিক্স ডি ফ্যাক্টো শেল) কিন্তু সঙ্গে বোর্ন নকশা idiosyncrasies অধিকাংশ সংশোধন শেল (এবং অতিরিক্ত বৈশিষ্ট্য অনেক, এবং অনেক আরও ব্যবহারকারী-বান্ধব / কম বিস্ময়কর)।
স্টাফেন চেজেলাস

সতর্কতা অবলম্বন করুন: zsh কখনও কখনও শূন্য বাইট পরিবর্তন করতে পারে: echo $(printf 'ab\0cd') | od -vAn -tx1c প্রিন্ট করে 62 61 62 20 63 64 0a`, এটি এমন একটি স্থান যেখানে কোনও NUL এর অস্তিত্ব থাকা উচিত।
ইসহাক

1
এবং এটি অন্য কোনও কিছু নয় (কিছুই নয়, শেল) পুনরুত্পাদন করবে। এটি একটি স্ক্রিপ্ট zsh এ খুব বিশেষ উপায়ে আচরণ করে। আমার মতে: zsh খুব চতুর হওয়ার চেষ্টা করছে।
ইসহাক

2
পসিক্স এসএইচ স্ট্যান্ডার্ডে নকশার দুর্বলতাগুলি "ফিক্সড" থাকার কারণে জেডএসপি স্ক্রিপ্টগুলি লেখার অভ্যস্ত হওয়া মানে এমন একটি অভ্যাসের অভ্যস্ত হয়ে যাওয়া যা অন্য কোনও শেল ব্যবহার করে বগি হবে। সিনট্যাক্সের ক্ষেত্রে এটি এমন সমস্যা নয় যা ভিন্ন ভাষার মতো নয় যে দক্ষতা বা অভ্যাসগুলি স্থানান্তরিত হওয়ার সম্ভাবনা নেই, তবে এটি ক্ষেত্রে নেই hand
চার্লস ডাফি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.