use std::net::TcpStream;
use std::io::Read;
use ssh2::Session;
use std::path::Path;
fn main() {
let tcp = TcpStream::connect("127.0.0.1:22").unwrap();
let mut sess = Session::new().unwrap();
sess.set_tcp_stream(tcp);
sess.handshake().unwrap();
sess.userauth_password("user", "password").unwrap();
let mut contents:Vec<u8> = Vec::new();
let sftp = sess.sftp().unwrap();
let mut stream = sftp.open(Path::new("/tmp/test.txt")).unwrap();
stream.read_to_end(&mut contents).unwrap();
let _ = std::fs::write(r"/tmp/test_out.txt", &contents);
}
Архив рубрики: Rust
Rust — sftp upload file
use std::net::TcpStream;
use std::io::Write;
use std::io::Read;
use std::fs::File;
use ssh2::Session;
use std::path::Path;
fn main() {
let tcp = TcpStream::connect("127.0.0.1:22").unwrap();
let mut sess = Session::new().unwrap();
sess.set_tcp_stream(tcp);
sess.handshake().unwrap();
sess.userauth_password("user", "pass").unwrap();
let sftp = sess.sftp().unwrap();
let mut local_file = File::open("/tmp/test.txt").expect("no file found");
let mut buffer:Vec<u8> = Vec::new();
let _ :u64 = local_file.read_to_end(&mut buffer).unwrap().try_into().unwrap();
sftp.create(&Path::new("/tmp/file.json"))
.unwrap()
.write_all(&buffer)
.unwrap();
}
Решено! Rust — не собирается под musl — ругаeтся на openssl в Linux.
Если вы решили использовать в своем проекте то, что нужнается в Openssl — будьте готовы что можете столкнуться с кучей ошибок при сборке, особенно если собираете под стандартную реализацию libc в musl.
При сборке cargo вам вывалит что -то подобное:
OPENSSL_DIR unset
cargo:rerun-if-env-changed=OPENSSL_NO_PKG_CONFIG
cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS_x86_64-unknown-linux-musl
cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS_x86_64_unknown_linux_musl
cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_ALLOW_CROSS
cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS
cargo:rerun-if-env-changed=PKG_CONFIG_x86_64-unknown-linux-musl
cargo:rerun-if-env-changed=PKG_CONFIG_x86_64_unknown_linux_musl
cargo:rerun-if-env-changed=TARGET_PKG_CONFIG
cargo:rerun-if-env-changed=PKG_CONFIG
cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64-unknown-linux-musl
cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64_unknown_linux_musl
cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_SYSROOT_DIR
cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR
run pkg_config fail: pkg-config has not been configured to support cross-compilation.
Install a sysroot for the target platform and configure it via
PKG_CONFIG_SYSROOT_DIR and PKG_CONFIG_PATH, or install a
cross-compiling wrapper for pkg-config and set it via
PKG_CONFIG environment variable.
--- stderr
thread 'main' panicked at /home/.cargo/registry/src/index.crates.io-6f17d22bba15001f/openssl-sys-0.9.102/build/find_normal.rs:190:5:
Could not find directory of OpenSSL installation, and this `-sys` crate cannot
proceed without this knowledge. If OpenSSL is installed and this crate had
trouble finding it, you can set the `OPENSSL_DIR` environment variable for the
compilation process.
Make sure you also have the development packages of openssl installed.
For example, `libssl-dev` on Ubuntu or `openssl-devel` on Fedora.
If you're in a situation where you think the directory *should* be found
automatically, please open a bug at https://github.com/sfackler/rust-openssl
and include information about your system as well as this message.
$HOST = x86_64-unknown-linux-gnu
$TARGET = x86_64-unknown-linux-musl
openssl-sys = 0.9.102
У меня такая фигня пошла, когда я решил добавить Sentry в свой проект.
Решение следующее:
Выполняем команды:
sudo apt-get update
sudo apt-get install -y musl-dev musl-tools linux-headers-$(uname -r)
sudo ln -s /usr/include/x86_64-linux-gnu/asm /usr/include/x86_64-linux-musl/asm && ln -s /usr/include/asm-generic /usr/include/x86_64-linux-musl/asm-generic && ln -s /usr/include/linux /usr/include/x86_64-linux-musl/linux
sudo mkdir /musl
wget https://github.com/openssl/openssl/archive/OpenSSL_1_1_1f.tar.gz
tar zxf OpenSSL_1_1_1f.tar.gz
cd openssl-OpenSSL_1_1_1f/
CC="musl-gcc -fPIE -pie -static -idirafter /usr/include/ -idirafter /usr/include/x86_64-linux-gnu/" ./Configure no-shared no-async --prefix=/musl --openssldir=/musl/ssl linux-x86_64
make depend
make -j$(nproc)
sudo make install
Экспортируем переменные окружения:
export PKG_CONFIG_ALLOW_CROSS=1
export OPENSSL_STATIC=true
export OPENSSL_DIR=/musl
Пробуем выполнять сборку:
cargo build --release --target=x86_64-unknown-linux-musl
Rust — увеличить по счетчику значение в HashMap
Я использовал хэш-таблицу в качестве дедубликатора имени ключа. Аналог ассоциативного массива в PHP, когда есть имя ключа и его значение и необходимо добавлять новые значения по имени ключа, при этом нам не нужно каждый раз дублировать эти имена ключей- они должны быть уникальными. Но при этом нам нужно для каждого ключа увеличить его значение, например на +1.
use std::collections::HashMap;
fn main() {
let mut fruits:HashMap<String, i32> = HashMap::new();
fruits.insert(String::from("sds"), 122);
fruits.insert(String::from("qqqq"), 22);
fruits.entry("sds".to_string()).and_modify(|count| *count += 1).or_insert(0);
let first_fruit = fruits.get("sds"); //123
println!("{:?}", first_fruit);}
Пример на Replit тут
Rust — вывести тип переменной
pub trait AnyExt {
fn type_name(&self) -> &'static str;
}
impl<T> AnyExt for T {
fn type_name(&self) -> &'static str {
std::any::type_name::<T>()
}
}
fn main(){
let my_number = 32.90;
println!("{}",my_number.type_name());
}
Результат:
f64
Rust — счетчик в ведущими нулями
Задача: вывести счетчик с ведущими нулями, пример 0001, 0002 и т.д.
Задача не сложная, но не стандартная и предполагает несколько вариантов реализации. Мой вариант реализован на том, что мы считаем длину стандартного int счетчика и в зависимости от нее добавляем перед ним нужно количество нулей, которые у нас являются уже строкой.
fn main(){
(1..1002).for_each(|n| {
let _str: String = n.to_string();
let lenght = _str.len();
let mut _zero = String::from("000");
if lenght == 2{
_zero = String::from("00");
}
else if lenght == 3{
_zero = String::from("0");
}
else if lenght == 4{
_zero = String::from("");
}
println!("{}{}",_zero, n);
});
}
Реализация этого же через match:
fn main(){
(1..1002).for_each(|n| {
let _str: String = n.to_string();
let lenght = _str.len();
match lenght {
2 => {println!("00{}", n);}
3 => {println!("0{}", n);}
4 => {println!("{}", n);}
_ => {println!("000{}", n);}
}
});
}
Rust — вырезать подстроку с начала и конца строки
fn main() {
let str = "/app/dima/var/test_log.stat.json";
//cut "/app/dima/var/"
let slice = &str[14..];
//cut ".stat.json"
let len = slice.len() - 10;
let substr = &slice[..len];
println!("{}", substr);
}
Логика такая:
- сначала удаляем путь — он содержит в данном случае постоянную длину.
- удаляем путь
- вычисляем длину строки
- удаляем длину подстроки .stat.json
Пример работающего кода
Rust — вывести тип переменной
/*
show me type of variable
use example: println!("{}",variable.type_name());
*/
pub trait AnyExt {
fn type_name(&self) -> &'static str;
}
impl<T> AnyExt for T {
fn type_name(&self) -> &'static str {
std::any::type_name::<T>()
}
}
fn main() {
let num = 1;
println!("{}",num.type_name());
}
Результат в данном случае будет :
i32
Rust — кросскомпиляция. Посмотреть набор инструментов.
Для кросскомпиляции в Rust нужно установить набор библиотек, необходимых для компиляции на определенной платформе.
Чтобы посмотреть установленные набор : rustup show
Чтобы добавит например musl , то делаем rustup target add x86_64-unknown-linux-musl
Смотрим rustup show
$ rustup show
.Default host: x86_64-unknown-linux-gnu
rustup home: /home/dima/.rustup
installed targets for active toolchain
--------------------------------------
x86_64-unknown-linux-gnu
x86_64-unknown-linux-musl
active toolchain
----------------
stable-x86_64-unknown-linux-gnu (default)
rustc 1.40.0 (73528e339 2019-12-16)
Теперь компилируем
$ cargo run --target=x86_64-unknown-linux-musl
Compiling cfg-if v0.1.10
Compiling ppv-lite86 v0.2.6
Compiling libc v0.2.66
Compiling getrandom v0.1.13
Compiling c2-chacha v0.2.3
Compiling rand_core v0.5.1
Compiling rand_chacha v0.2.1
Compiling rand v0.7.2
Compiling read_file v0.1.0 (/home/dima/Rust/read_file)
Finished dev [unoptimized + debuginfo] target(s) in 36.55s
Running `target/x86_64-unknown-linux-musl/debug/read_file`
Random u8: 252
Random u16: 4832
Random u32: 141195676
Random i32: -1677746107
Random float: 0.22141390568216823
Rust: компиляция. Ошибка: could not compile `libc`
На Ubuntu встретился с такой ошибкой при компиляции: error: could not compile libc
Лечиться так: sudo apt install build-essential